yaws-2.0.2/0000775000175000017500000000000012605312015007474 500000000000000yaws-2.0.2/Makefile.in0000664000175000017500000011533212605311445011474 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ @WINDOWS_FALSE@am__append_1 = c_src @MINGW_TRUE@am__append_2 = win32 subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ $(srcdir)/yaws.pc.in \ $(top_srcdir)/test/eunit//subconfig_DATA/yaws_absolute.conf.in \ $(top_srcdir)/test/eunit//subconfig_DATA/yaws_absolute_no_wildcard.conf.in \ $(top_srcdir)/test/eunit//subconfig_DATA/global_absolute_subconfig.conf.in \ $(top_srcdir)/test/eunit//subconfig_DATA/global_absolute_no_wildcard_subconfig.conf.in \ $(top_srcdir)/test/support/yaws.conf.in \ $(top_srcdir)/applications/wiki/scripts/addFile.in \ $(top_srcdir)/applications/wiki/scripts/getPassword.in \ $(top_srcdir)/applications/wiki/scripts/importFiles.in \ $(top_srcdir)/applications/wiki/scripts/updateWiki.in \ ChangeLog ac-aux/ar-lib ac-aux/compile ac-aux/config.guess \ ac-aux/config.sub ac-aux/install-sh ac-aux/missing \ ac-aux/ltmain.sh $(top_srcdir)/ac-aux/ar-lib \ $(top_srcdir)/ac-aux/compile $(top_srcdir)/ac-aux/config.guess \ $(top_srcdir)/ac-aux/config.sub \ $(top_srcdir)/ac-aux/install-sh $(top_srcdir)/ac-aux/ltmain.sh \ $(top_srcdir)/ac-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.pc \ test/eunit//subconfig_DATA/yaws_absolute.conf \ test/eunit//subconfig_DATA/yaws_absolute_no_wildcard.conf \ test/eunit//subconfig_DATA/global_absolute_subconfig.conf \ test/eunit//subconfig_DATA/global_absolute_no_wildcard_subconfig.conf \ test/support/yaws.conf applications/wiki/scripts/addFile \ applications/wiki/scripts/getPassword \ applications/wiki/scripts/importFiles \ applications/wiki/scripts/updateWiki CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgconfigdir)" DATA = $(pkgconfig_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = src ebin include priv c_src win32 examples/src \ examples/ebin examples/include test doc man scripts www/code \ www/shoppingcart DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ ACLOCAL_FLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src ebin include priv $(am__append_1) $(am__append_2) \ examples/src examples/ebin examples/include test doc man \ scripts www/code www/shoppingcart APPDIRS = applications/chat applications/mail applications/wiki applications/yapp EXTRA_DIST = ChangeLog known_dialyzer_warnings LICENSE \ README.md README.osx README.pkg-config \ rebar.config rebar.config.script two-mode-mode.el vsn.mk \ include.mk erlang_deps.mk ssl munin contrib www rel @MINGW_FALSE@pkgconfigdir = $(libdir)/pkgconfig @MINGW_FALSE@pkgconfig_DATA = yaws.pc all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): yaws.pc: $(top_builddir)/config.status $(srcdir)/yaws.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ test/eunit//subconfig_DATA/yaws_absolute.conf: $(top_builddir)/config.status $(top_srcdir)/test/eunit//subconfig_DATA/yaws_absolute.conf.in cd $(top_builddir) && $(SHELL) ./config.status $@ test/eunit//subconfig_DATA/yaws_absolute_no_wildcard.conf: $(top_builddir)/config.status $(top_srcdir)/test/eunit//subconfig_DATA/yaws_absolute_no_wildcard.conf.in cd $(top_builddir) && $(SHELL) ./config.status $@ test/eunit//subconfig_DATA/global_absolute_subconfig.conf: $(top_builddir)/config.status $(top_srcdir)/test/eunit//subconfig_DATA/global_absolute_subconfig.conf.in cd $(top_builddir) && $(SHELL) ./config.status $@ test/eunit//subconfig_DATA/global_absolute_no_wildcard_subconfig.conf: $(top_builddir)/config.status $(top_srcdir)/test/eunit//subconfig_DATA/global_absolute_no_wildcard_subconfig.conf.in cd $(top_builddir) && $(SHELL) ./config.status $@ test/support/yaws.conf: $(top_builddir)/config.status $(top_srcdir)/test/support/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $@ applications/wiki/scripts/addFile: $(top_builddir)/config.status $(top_srcdir)/applications/wiki/scripts/addFile.in cd $(top_builddir) && $(SHELL) ./config.status $@ applications/wiki/scripts/getPassword: $(top_builddir)/config.status $(top_srcdir)/applications/wiki/scripts/getPassword.in cd $(top_builddir) && $(SHELL) ./config.status $@ applications/wiki/scripts/importFiles: $(top_builddir)/config.status $(top_srcdir)/applications/wiki/scripts/importFiles.in cd $(top_builddir) && $(SHELL) ./config.status $@ applications/wiki/scripts/updateWiki: $(top_builddir)/config.status $(top_srcdir)/applications/wiki/scripts/updateWiki.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) all-local installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-libtool \ distclean-local distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local uninstall-pkgconfigDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool clean-local cscope cscopelist-am ctags ctags-am \ dist dist-all dist-bzip2 dist-gzip dist-hook dist-lzip \ dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \ distclean-generic distclean-libtool distclean-local \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local 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-pkgconfigDATA install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-local uninstall-pkgconfigDATA @WINDOWS_FALSE@ # don't c-compile anything on win32 (yet) @WINDOWS_FALSE@ # I don't know how to make a linked in driver using gcc, or any other compiler @WINDOWS_FALSE@ # there, and have no intentions of finding out all-local: clean-local: $(AM_V_at)rm -f dialyzer_warnings install-data-local: all $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(wwwdir) $(AM_V_at)(cd @top_srcdir@; tar cf - www ) | (cd $(DESTDIR)$(wwwdir)/..; tar xf - ) $(AM_V_at)chmod -R u+rw $(DESTDIR)$(wwwdir) $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(logdir) $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(sysconfdir)/yaws $(AM_V_at)$(INSTALL) -m 644 @srcdir@/ssl/yaws-cert.pem $(DESTDIR)$(sysconfdir)/yaws $(AM_V_at)$(INSTALL) -m 644 @srcdir@/ssl/yaws-key.pem $(DESTDIR)$(sysconfdir)/yaws $(AM_V_at)$(INSTALL) -m 644 @srcdir@/ssl/dhparams.pem $(DESTDIR)$(sysconfdir)/yaws @echo "-------------------------------" @echo @echo "** etc files went into $(sysconfdir)" @echo "** executables went into $(bindir)" @echo "** library files went into $(ERLANG_INSTALL_LIB_DIR_yaws)" @echo "** logs went into $(logdir)" @echo "** doc files went into $(docdir)" @echo "** man files went into $(mandir)" @echo "** default docroot went into $(wwwdir)" $(AM_V_at)if test $(yawsdir) != $(ERLANG_INSTALL_LIB_DIR_yaws); then \ echo; \ if test -d $(DESTDIR)$(yawsdir) && test ! -h $(DESTDIR)$(yawsdir); then \ backupdir="$(DESTDIR)$(yawsdir).backup"; \ echo "backup old yaws directory into $${backupdir}"; \ mv $(DESTDIR)$(yawsdir) $${backupdir}; \ else \ $(INSTALL) -d `dirname $(yawsdir)`; \ rm -f $(DESTDIR)$(yawsdir); \ fi; \ $(LN_S) -f $(ERLANG_INSTALL_LIB_DIR_yaws) $(DESTDIR)$(yawsdir); \ echo "create link $(ERLANG_INSTALL_LIB_DIR_yaws) -> $(yawsdir)"; \ fi @echo @echo "--------------------------------" uninstall-local: $(AM_V_at)(cd @top_srcdir@/www && find * -type f -exec rm -f $(DESTDIR)$(wwwdir)/{} \;) $(AM_V_at)(cd @top_srcdir@/www && find * -type d -exec rm -fr $(DESTDIR)$(wwwdir)/{} \;) $(AM_V_at)[ ! -h $(yawsdir) ] || rm -f $(DESTDIR)$(libdir)/yaws $(AM_V_at)rm -r $(DESTDIR)$(sysconfdir)/yaws/yaws-cert.pem $(AM_V_at)rm -r $(DESTDIR)$(sysconfdir)/yaws/yaws-key.pem $(AM_V_at)rm -r $(DESTDIR)$(sysconfdir)/yaws/dhparams.pem debug: $(MAKE) DEBUG_ERLC_FLAGS=" -Ddebug" CFLAGS="-Werror -Wall -O0 -g" docs: doc doc: $(AM_V_at)( cd doc && $(MAKE) doc ) test: check cleantest: $(AM_V_at)( cd test && $(MAKE) clean ) yaws.plt: $(AM_V_GEN)dialyzer --build_plt -r ebin --output_plt yaws.plt \ -r $(ERLANG_LIB_DIR_kernel) \ -r $(ERLANG_LIB_DIR_stdlib) \ -r $(ERLANG_LIB_DIR_sasl) \ -r $(ERLANG_LIB_DIR_erts) \ -r $(ERLANG_LIB_DIR_compiler) \ -r $(ERLANG_LIB_DIR_crypto) \ -r $(ERLANG_LIB_DIR_xmerl) dialyzer: all yaws.plt $(AM_V_at)$(DIALYZER) -q --plt yaws.plt -r ebin > dialyzer_warnings || true $(AM_V_at)if diff -U0 @srcdir@/known_dialyzer_warnings dialyzer_warnings ; then \ echo dialyzer check passed ; \ exit 0 ; \ else \ exit 1 ; \ fi dist-hook: $(AM_V_at)for a in $(APPDIRS); do \ $(INSTALL) -d $(distdir)/$$a; \ (cd $$a && $(MAKE) top_distdir=../../$(distdir) \ distdir=../../$(distdir)/$$a distdir); \ done find $(distdir) -type d -name .deps | xargs rm -rf distclean-local: $(AM_V_at)[ ! -h include/yaws.hrl ] || rm -f include/yaws.hrl $(AM_V_at)[ ! -h include/yaws_api.hrl ] || rm -f include/yaws_api.hrl $(AM_V_at)[ ! -h priv/mime.types ] || rm -f priv/mime.types $(AM_V_at)for a in $(APPDIRS); do \ (cd $$a && $(MAKE) distclean); \ done mkinstaller: cleaninstaller $(AM_V_at)if [ -z "$(UNIX2DOS)" -a -z "$(TODOS)" ]; then \ echo "No unix2dos/todos program found"; \ echo "Run apt-get install dos2unix/tofrodos"; \ exit 1; \ fi $(AM_V_at)if [ ! -d "$(INSTALL_BUILDER)" ]; then \ echo "No installer-builder found"; \ echo "For more information, read win32/README.developer"; \ exit 1; \ fi $(AM_V_at)$(MAKE) distdir $(AM_V_at)$(MKDIR_P) $(distdir)/_build $(AM_V_at)(cd $(distdir)/_build && ../configure \ --host i586-mingw32msvc --prefix=/ --docdir=/doc --mandir=/man \ wwwdir=/www logdir=/logs yawsdir=/ confdir=/ appsdir=/applications \ yappdir=/applications/yapp INSTALL_BUILDER=$(INSTALL_BUILDER)) $(AM_V_at)(cd $(distdir)/_build && $(MAKE) install DESTDIR=@abs_builddir@/$(distdir)/_inst) $(AM_V_at)(cd $(distdir)/_build && $(MAKE) installapps DESTDIR=@abs_builddir@/$(distdir)/_inst) $(AM_V_at)(cd $(distdir)/_build/win32 && $(MAKE) mkinstaller DESTDIR=@abs_builddir@/$(distdir)/_inst) $(AM_V_at)cp $(distdir)/*.exe @builddir@ $(AM_V_at)rm -fr $(distdir) cleaninstaller: $(AM_V_at)rm -f *.exe $(AM_V_at)rm -fr $(distdir) apps: $(APPDIRS) $(APPDIRS): $(AM_V_at)(cd $@ && $(MAKE) all) cleanapps: $(AM_V_at)for a in $(APPDIRS); do \ (cd $$a && $(MAKE) clean); \ done installapps: apps $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(appsdir) $(AM_V_at)for a in $(APPDIRS); do \ (cd $$a && $(MAKE) install); \ done uninstallapps: apps $(AM_V_at)for a in $(APPDIRS); do \ (cd $$a && $(MAKE) uninstall); \ done fullinstall: install installapps fulluninstall: uninstall uninstallapps fullclean: clean cleantest cleaninstaller cleanapps .PHONY: test doc $(APPDIRS) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/doc/0000775000175000017500000000000012605312015010241 500000000000000yaws-2.0.2/doc/Makefile.in0000664000175000017500000004134112605311445012237 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = doc DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ IMG_EPS = a.eps b.eps layout.eps yaws_head.eps IMG_PDF = $(IMG_EPS:.eps=.pdf) EXTRA_DIST = $(IMG_EPS) overview.edoc README.rss yaws.tex all: all-am .SUFFIXES: .SUFFIXES: .eps .pdf $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @CAN_BUILD_DOC_FALSE@clean-local: @CAN_BUILD_DOC_FALSE@uninstall-local: clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-local @CAN_BUILD_DOC_TRUE@doc: yaws.ps yaws.pdf @CAN_BUILD_DOC_TRUE@install-data-local: doc @CAN_BUILD_DOC_TRUE@ $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(docdir) @CAN_BUILD_DOC_TRUE@ $(AM_V_at)$(INSTALL) -m 644 yaws.pdf $(DESTDIR)$(docdir) @CAN_BUILD_DOC_TRUE@ $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(wwwdir) @CAN_BUILD_DOC_TRUE@ $(AM_V_at)$(INSTALL) -m 644 yaws.ps $(DESTDIR)$(wwwdir) @CAN_BUILD_DOC_TRUE@ $(AM_V_at)$(INSTALL) -m 644 yaws.pdf $(DESTDIR)$(wwwdir) @CAN_BUILD_DOC_TRUE@uninstall-local: @CAN_BUILD_DOC_TRUE@ $(AM_V_at)rm -f $(DESTDIR)$(docdir)/yaws.pdf @CAN_BUILD_DOC_TRUE@ $(AM_V_at)rm -f $(DESTDIR)$(wwwdir)/yaws.ps @CAN_BUILD_DOC_TRUE@ $(AM_V_at)rm -f $(DESTDIR)$(wwwdir)/yaws.pdf @CAN_BUILD_DOC_TRUE@clean-local: @CAN_BUILD_DOC_TRUE@ $(AM_V_at)rm -f *.ps *.dvi *.log *.aux *.pdf *.toc *.out @CAN_BUILD_DOC_FALSE@doc: @CAN_BUILD_DOC_FALSE@ @echo "SKIPPED:" @CAN_BUILD_DOC_FALSE@ @if [ -z "$(DVILATEX)" ]; then \ @CAN_BUILD_DOC_FALSE@ echo " latex required to build documentation"; \ @CAN_BUILD_DOC_FALSE@ fi @CAN_BUILD_DOC_FALSE@ @if [ -z "$(DVIPS)" ]; then \ @CAN_BUILD_DOC_FALSE@ echo " dvips required to build documentation"; \ @CAN_BUILD_DOC_FALSE@ fi @CAN_BUILD_DOC_FALSE@ @if [ -z "$(PDFLATEX)" ]; then \ @CAN_BUILD_DOC_FALSE@ echo " pdflatex required to build documentation"; \ @CAN_BUILD_DOC_FALSE@ fi @CAN_BUILD_DOC_FALSE@ @if [ -z "$(EPSTOPDF)" ]; then \ @CAN_BUILD_DOC_FALSE@ echo " epstopdf required to build documentation"; \ @CAN_BUILD_DOC_FALSE@ fi @CAN_BUILD_DOC_FALSE@install-data-local: doc yaws.ps: yaws.dvi $(AM_V_GEN)TEXINPUTS="$${TEXTINPUTS}:@srcdir@" $(DVIPS) -q -o $@ $< yaws.pdf: yaws.tex $(IMG_PDF) $(AM_V_GEN)TEXINPUTS="$${TEXTINPUTS}:@srcdir@" $(PDFLATEX) yaws.tex > /dev/null $(AM_V_at)TEXINPUTS="$${TEXTINPUTS}:@srcdir@" $(PDFLATEX) yaws.tex > /dev/null yaws.dvi: yaws.tex $(IMG_EPS) $(AM_V_GEN)TEXINPUTS="$${TEXTINPUTS}:@srcdir@" $(DVILATEX) yaws.tex > /dev/null $(AM_V_at)TEXINPUTS="$${TEXTINPUTS}:@srcdir@" $(DVILATEX) yaws.tex > /dev/null .eps.pdf: $(AM_V_GEN)$(EPSTOPDF) --outfile=$@ $< > /dev/null .NOTPARALLEL: # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/doc/yaws_head.eps0000664000175000017500000002667612605311412012657 00000000000000%!PS-Adobe-3.0 EPSF-3.0 %%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner %%Title: /home/klacke/yaws/yaws/www/icons/yaws_head.eps %%CreationDate: Sun Nov 10 22:11:03 2002 %%DocumentData: Clean7Bit %%LanguageLevel: 2 %%Pages: 1 %%BoundingBox: 14 14 815 75 %%EndComments %%BeginProlog % Use own dictionary to avoid conflicts 10 dict begin %%EndProlog %%Page: 1 1 % Translate for offset 14.173228 14.173228 translate % Translate to begin of first scanline 0.000000 60.000000 translate 800.000000 -60.000000 scale % Image geometry 800 60 8 % Transformation matrix [ 800 0 0 60 0 0 ] % Strings to hold RGB-samples per scanline /rstr 800 string def /gstr 800 string def /bstr 800 string def {currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop} {currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop} {currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop} true 3 %%BeginData: 10683 ASCII Bytes colorimage JcC<$JcC<$JcC<$iW"E~> JcC<$JcC<$JcC<$iW"E~> JcC<$JcC<$JcC<$iW"E~> JcC<$JcC<$JcC<$iW"E~> JcC<$JcC<$JcC<$iW"E~> JcC<$JcC<$JcC<$iW"E~> rr7PnJ]t[KJcGECJ]r\h^!-ESJ,~> rr2sSJH16$])VgeJcGHD!1AB rr2sSJH16$])VgeJcGHD!1AB rr;-)!L[QQbQaIk1B7D2R=WS9b^ofes+/CFbe;6us*t~> s8N(eJH16$\c;^dJcGECJH16$]`8&VrVqB~> s8N(eJH16$\c;^dJcGECJH16$]`8&VrVqB~> s8V6*"(hN51Yg1SB))E,R=WS:b^ofes+/CFbe20us*t~> s8N(2JH16$\c;^dJcGEC!+pc^JH3Ca!+u30J,~> s8N(2JH16$\c;^dJcGEC!+pc^JH3Ca!+u30J,~> s8V6*!&OTS!&NNV!1EQ]!1AD^L s8N'TJH16$\c;^dJcGEC!1AB s8N'TJH16$\c;^dJcGEC!1AB s8V6*qu?^QiQM:ip](>,R=WS9b^ofds+/CFbe;7!s*t~> s8RWMJH34\!&K3+p&>$9JH16$]`A$2J,~> s8RWMJH34\!&K3+p&>$9JH16$]`A$2J,~> s8V6*qZ$UPj3.Ol1\h"NAqA0Yb^ofds+/CFbe;7!s*t~> s8RWMJH34\!&K3+o`'IBJH3@`rVqB~> s8RWMJH34\!&K3+o`'IBJH3@`rVqB~> s8V6*!&OKP!+t<9!+u$,!L`t=b_+,js7H>Bb^n!Obl.Ql~> s8N'TJH16$\c;^dJcGBB!&K0+JH3Fb!&OTRJ,~> s8N'TJH16$\c;^dJcGBB!&K0+JH3Fb!&OTRJ,~> s8V6*!1EZ`!1Dun!1EW_!1AD^J]r]Fo`'KdJ]tgOrVqB~> s8N'TJH16$\c;^dJcGBB!&K0+JH3Fb!&OTRJ,~> s8N'TJH16$\c;^dJcGBB!&K0+JH3Fb!&OTRJ,~> rr;-)q#CD_kKN`%J]r\hs3-&oo`'KdJ]tjPr;V9~> s8N(eJH16$\c;^dJcGBB!+pc^JH3Fb!1EfcJ,~> s8N(eJH16$\c;^dJcGBB!+pc^JH3Fb!1EfcJ,~> rr;-)!+u'-!&Ni_!+u'-!1AD^J^"/ rr7NLJH37]!&K3+o`"oZJH16$^B"33J,~> rr7NLJH37]!&K3+o`"oZJH16$^B"33J,~> rr;*(q#CCNlHB6rq>^M`J]r\hrlfrno`'KdJ]tmQqu;0~> rr2t1JH16$])VgeJcGBB!+pc^JH3Ic!1EcbJ,~> rr2t1JH16$])VgeJcGBB!+pc^JH3Ic!1EcbJ,~> rVu$(!1EW_!+tQ@!&OKP!+pf+J^"):JcGBBJ]r\h^WcTTJ,~> rVqEKJH3:^!&K3+o`"nIJH16$_#OHkqu;0~> rVqEKJH3:^!&K3+o`"nIJH16$_#OHkqu;0~> r;Yp'!&OEN!1E5u!+u*.!&L@nrgA>]hTUQNo`'KdJ]tpRqYu'~> rVlkcJH16$]DqpfJcGBB!&K0+JH3Ld!6k??J,~> rVlkcJH16$]DqpfJcGBB!&K0+JH3Ld!6k??J,~> r;Ym&p](;^m`bM-Vp#72Ahu7>!!-]"J^!,tJcGBBJ]r\h_9D`TJ,~> r;QaQJH16$]`8$gJcGBBJH16$_#OJ'qYu'~> r;QaQJH16$]`8$gJcGBBJH16$_#OJ'qYu'~> qu>g&!+u$,!&O)f!&OKP!1EN(qjI*#!1DE^!gtiVpribN1\:YI1P*d0b^ofds+/CFbehU!s*t~> qu6XPJH16$^&S-hJcGEC!6fuoJH3Oe!1EZ_J,~> qu6XPJH16$^&S-hJcGEC!6fuoJH3Oe!1EZ_J,~> qZ#^%!&OEN!&O/h!1E]a!+tuL!G4.a!<4hTRJ>#*!!&G?bQDGW!&OJq!&O*EJ^!,tJcGECJ]r\h _T_cSJ,~> qYpOOJH16$^An6iJcGEC!+pc^JH3Rf!1EW^J,~> qYpOOJH16$^An6iJcGEC!+pc^JH3Rf!1EW^J,~> q>]U$p](;+o$$t2!&OGp!L[Ql!!-]"qof%Pr;bTr!LYbC!!"hQbQ)8C!.iARb^ofes+/CFbeqZu s*t~> q>UFNJH16$^]4?jJcGECJH16$_uKfobkM-f~> q>UFNJH16$^]4?jJcGECJH16$_uKfobkM-f~> q#BO$!1ET^!+tlI!+u*.q9/i,nGiPFqonp;n]V-(1B95!o#q*%qu?_/rQG6tmJm6!J^!,tJcGEC J]r\h`6@oSJ,~> q#:>+JH16$_#OHkJcGHD!+pc^JH3Xh!+tp(J,~> q#:>+JH16$_#OHkJcGHD!+pc^JH3Xh!+tp(J,~> pAa@#!1ET^!1EQ)!1E]a!1E]-!+t["!+u/QqZ$UPo?76'1]7:R1\AllAi'>b!+u5S!1E6T!+pf+ iQQlQpA]]fJ]u*WoDa=~> p\t5]JH16$_>jTmb^ofhrrC8o!.b-i!!+mDo`'F~> p\t5]JH16$_>jTmb^ofhrrC8o!.b-i!!+mDo`'F~> p&F7"!+u!+!1EW+!LYbA!!"hObQ+'u!!&Gcbk_;>RIn]'1]%.PRJ+i)RJHm`B)^!S1\(PG1B;$< bhgQps7lVFb^n!Xbjk^`~> pAY0;1P#OW!5ed:AqC!Wrr=j+!.b-j!!&GXs*t~> pAY0;1P#OW!5ed:AqC!Wrr=j+!.b-j!!&GXs*t~> oDe(!!&OBM!1EZ,!+u-/!&OGp!&O!B!+u2R!&OHOoumDJq#L05!+u$,!1Ei1p&P+Ks-\G^g!#$I qYu,jJ]u0Yn,In~> o`"r[1P#OW!5nj;AqC!Yrr?Y^!.b-l!!+lfnGe"~> o`"r[1P#OW!5nj;AqC!Yrr?Y^!.b-l!!+lfnGe"~> nc.mu!&OBM!1E`.!1E]a!1EZ,!+u'-s"j[e!&OEN!+u2R!+u'-!+trK!&OEN!1EZ,!+u!+rQP$: !Ag-pbgajfs8;nJb^n!ZbjGF\~> o)A`Y1P#OW!6"p=1X(FMrVlk0JH16$aoDHSRI:**~> o)A`Y1P#OW!6"p=1X(FMrVlk0JH16$aoDHSRI:**~> n,M^tpAb2]rQG80qZ$V.pWWQ'qTSa8!&OSt!+u$,!1EW+!1ET^!&OJq!1ET^!&OStp],lhd*.(@ s8RYoJ]u<]l2Q8~> nG`QXAi"u nG`QXAi"u lMp@t!1EQ]"(mtFbk_>)bQ)8N!<(+ARJ?g_1\f/oB(l<%bQ'Ho!!$X0bQ)8N!!&F m/I.2R59BoJH3dl!Ag-rrrC8o!.b-s!!>#hREXjoJ,~> m/I.2R59BoJH3dl!Ag-rrrC8o!.b-s!!>#hREXjoJ,~> k5Y%s!1EN\!&OHO!1E,r!+u$,r64p9!1EZ,p&G)\r6,//pAb2]rQG80q#CCNJ]uE`L&Z_JJ]uNc i;\<~> kl:\,!G4-=!.b-o!!+mDL]7D!1P#OW!7LrJAcU'7s*t~> kl:\,!G4-=!.b-o!!+mDL]7D!1P#OW!7LrJAcU'7s*t~> ir9&'s7jeB))H)bQ'Ho!;an>B(c3)B)KjQB(l<&bQ+(,!!"g+bfn:gs+/CFbgXek s*t~> j8T5*R:\7+!.b-q!!-]"N;ipH1P#OW!7h,P1M4kThZ&*~> j8T5*R:\7+!.b-q!!-]"N;ipH1P#OW!7h,P1M4kThZ&*~> h#I8q!&O-Fkfa#_q#CD_rQG7Rp](;+qof$rp&G(KrQG80pAb2*qTJqOq#CCNJ]u9\QN%*3s3/^e J]r\hf$"0pbh)lF~> hZ*W"!G4-=!.b-s!!4sEba\Y4bl=+2B)aZ#hB$Ap-J,~> hZ*W"!G4-=!.b-s!!4sEba\Y4bl=+2B)aZ#hB$Ap-J,~> f)G`onc/ZXoZ[0"rQG80p](;^rQG80pAb2]r64d5rQG7RpAb2]q9/i,q#CFOR=WT&bbtICbl>oe J]r\hcccFibgHH@~> f`)#sR:_!MJH4't"#FQ5bcCaKbaH[eR:\62JH16$dK';'s-Wl2e,Op~> f`)#sR:_!MJH4't"#FQ5bcCaKbaH[eR:\62JH16$dK';'s-Wl2e,Op~> ec,W;oDel'p<3PL1\^qO1B96*!!&GbbQ'Ho!!"hRbQ)8I!!$X1bkD);1\])nRJ6a^R=WT#bQ7af \c2cUs31Lob^n!ZbQ7afbl<1~> ec,W;JH16$bl@l&AnK92^]48V". ec,W;JH16$bl@l&AnK92^]48V". eGo1A!&O>mkPtUNr6,-spAb2*rljs6"#J0FB(l9*B(aCC!!$V^be2.#s3/mj"3gehs+/CFbeVF' s3/I^J,~> eGo.@!&K0+JH41"s"j[es-`l1g].2q"IWkiAsrTRJH16$`W-/uAnIITbfBa6~> eGo.@!&K0+JH41"s"j[es-`l1g].2q"IWkiAsrTRJH16$`W-/uAnIITbfBa6~> eGfM\p&G*:rVloBs8C19!<-R11\C_JRJb8/RJ$U^1RU&q!!-[fqZ$Y/bk;&/bQ+(+!!$V^bco:k s8L4Bs8L4Es3/^eJ]r\hWltMDbeF+-~> eGfM\p&GBBs8U eGfM\p&GBBs8U eGfN:pAb2*p\t5]q#CD,qof$rpAb2]qonF-!bTYgq>^LOpAb1Lo?72Hp](;^J]r\hJ]r\hf$"0p bdRP%~> eGfN:pAb2*p\t5]JH16$JH16$JH5?Cs"j[e!h%9V\Gq'~> eGfN:pAb2*p\t5]JH16$JH16$JH5?Cs"j[e!h%9V\Gq'~> e,T.B!+u!*!1EZ`"D7]6bl@XcpAk'6!+tX!!h%9Vmf;q&!1EQ]J]r\hJ]r\hhol-$bcUnq~> e,T.B!+u!*!1EZ`#A23(R@.YC1P#OW!.b-$!/ppX1B_ e,T.B!+u!*!1EZ`#A23(R@.YC1P#OW!.b-$!/ppX1B_ e,T.B!1ET]!1EZ`q#:=Mp]107!1E6Trlb@SnGiQ$o#q)GpAb2]J]r\hJ]r\hl-'2.bbY8h~> e,T.B!1ET]!1EZ`q#:=MJH16$JH16$QiR.Bs(2>#bflsaJ,~> e,T.B!1ET]!1EZ`q#:=MJH16$JH16$QiR.Bs(2>#bflsaJ,~> e,T.B!&O?KqZ$UPq#:=Mq#CCNr;QlCs3*:g!!$X0bjb](bQ+()!!$V^b^muhb^n"3bQImhs3-o2 J,~> e,T.B!&O?KqZ$UPq#:=Mq#CIPs8W)B!bRj4JH16$JH16$[/g1^!bRj4rlgo4J,~> e,T.B!&O?KqZ$UPq#:=Mq#CIPs8W)B!bRj4JH16$JH16$[/g1^!bRj4rlgo4J,~> e,T.B!&O?K!1E]a!6k<>!6k3sbl>nH s*t~> e,T.B!&O?K!1E]a!6k<>!6k3 e,T.B!&O?K!1E]a!6k<>!6k3 e,T+A!6k0:!&OKP!6k??!&OBM!1EW^nGiPFqu6XPo`+u(o?72HoDelZJ]r\hJ]s5""96UFb^ofo s*t~> e,T+A!6k0:!&OKP!6k??!&OBM!1EW^nGiVHs8W)B!LY`p!.b-$!.b.8!<"\VAsm8!RJtE_s*t~> e,T+A!6k0:!&OKP!6k??!&OBM!1EW^nGiVHs8W)B!LY`p!.b-$!.b.8!<"\VAsm8!RJtE_s*t~> e,T+A!1EQ\!6k9>"_O1Hs-Y\;!!(7rr=kL!!+n"rr3)Es31N?bQ'Hk!!$V^b^muh bb*)]s31MeJcG3=J,~> e,T+A!1EQ\!6k9>"_O1Hs-Y\;!!(7rr=kL!!tHLbflKCAsm7CrA0!)JH16$PlU_< "D4'6R:cEAJcG?AJ,~> e,T+A!1EQ\!6k9>"_O1Hs-Y\;!!(7rr=kL!!tHLbflKCAsm7CrA0!)JH16$PlU_< "D4'6R:cEAJcG?AJ,~> e,T+A!&Ooes3-&ohZ&*~> e,T+A!&OsHh"_O07 R:_lab^ofQs*t~> e,T+A!&OsHh"_O07 R:_lab^ofQs*t~> e,T(@!6k-9!1E3S!+ts)!+tj'!6k6oeb^of2s*t~> e,T(@!6k-9!1E3S!+ts)!+tj'!6k6 e,T(@!6k-9!1E3S!+ts)!+tj'!6k6 e,T(@!1EKZ!6jj2o`+Ra!&O e,T(@!1EKZ!6jj2o`+Ra!&O e,T(@!1EKZ!6jj2o`+Ra!&O e,T(@!&O3G!&O-F!6k*8!1EQ]!Ahs\rrAJ[!!4rgbe*n;bQ9R#1Z?OZ1B960bQ0L"e]\)_!&NWY !&L_#JcCW-J,~> e,T(@!&O3G!&O-F!6k*8!1EQ]!Ahs\rrAJ[!!4rgbe3rUb^fbF!5SX8b^oePs*t~> e,T(@!&O3G!&O-F!6k*8!1EQ]!Ahs\rrAJ[!!4rgbe3rUb^fbF!5SX8b^oePs*t~> e,T%?!6k$6!1EEY!1EEX!+u!+!1DgG".e7X!1Ei1"IV%G1R\6d!gs$ErQG@"!&L&@bl0EtbQO=ibVK7rbQ+(+bQ)8Sbl9I( Asple1B;$TrQG;11]@CRbl9I*AspleR5<&C!&OPss"jYus"apmREWmC1X%WT]$,a*MZ82~> e,T%?!6k$6!1EEY!1EEX!+u!+!1DgG". e,T%?!6k$6!1EEY!1EEX!+u!+!1DgG". e,T%?!1E?V!G4.^!!&GVrr=kO!!$Vhs.dg<1]GVu1]GSu1]7:XbaC6e!&J6`bT-[qAcOX2bVK5! 1B^$6!&OMr!Aa`TbQp"mbfjZ!bfhmA!<:7C 1]@@^1RZJ21B7D2REWl2r;clA#%dik!&FUerlbO%!1D'T1]7=RbQMMX1B95Bb^oeOs*t~> e,T%?!1E?V!G4.^!!&GVrr=kO!!$VirrAI e,T%?!1E?V!G4.^!!&GVrr=kO!!$VirrAI eGfNmoDel'mf*?VAi'Ac!Ag/2rr=kQ!!$Vgs.ddK1B eGfNmoDel'mf*?VAi'Ac!Ag/2rr=kQ!!$Vgs+(0$!5\^9b^oePs*t~> eGfNmoDel'mf*?VAi'Ac!Ag/2rr=kQ!!$Vgs+(0$!5\^9b^oePs*t~> eGfNmo)R/;"IWjXB$?,3UW`n0!!(4C!<11C1B@A0rgYC!&MjC 1B>XeR/f&BbR$'*1X%X2bfhjCrA+PDbVK7obQF75!6kEB'$L=UbfhjC1G]"eREPX2baC7CrlkBB%% 5>`1B93e!&L%e1B@Eu&t&_UbVK6ebfhjC1G]"eRERGe\'0F'MZ82~> eGfNmo)R/;"IWjXB$?,3!+pc^JH3Rf!6g#oMuS;~> eGfNmo)R/;"IWjXB$?,3!+pc^JH3Rf!6g#oMuS;~> eGfNmo)Jd7JcF4!UW`_+rVuq1rlkBBqTJs?1\o5t!&MhT!<11O1BYC1B>YC!!*#B!<=qT bR$'*RERHCbfg%eqof's!;F\;1]@@SB)Vc5B$AI!!;k"?!!CG$!&OVu#+5Gkbfg%eqof's!<(+A 1]@@S1]GVu!;jt@1B=o.JcCW-J,~> eGfNmo)Jd7JcF7"!1AB eGfNmo)Jd7JcF7"!1AB eGfNmo)Jd7JcF4!UYC1B>YCR/d4C!1Ei1!<=qT bR--+bfhk!bfhjCRJb801B@0n!+u31"3`P$!<11D1BN!1B eGfNmo)Jd7JcF4!JH16$_Z0\\JcCZ.J,~> eGfNmo)Jd7JcF4!JH16$_Z0\\JcCZ.J,~> eGfNmo)Jd7JcF4!U^$6AsrYB!&ODo"IV%G!&OVus"j]!s"jVts"aYCrQG6trQP9t s3(L"RJtD51B94CRJtD11\])uR/d5TbfhkTrQGI%!&J5Tbfp%d!&OVu"IV%G1R\6d">^$6AsrYB !&OPs!LWrbbQK^%1M3'SbQ'H.b^oeOs*t~> eGfNmo)Jd7JcF4!!+pc^JH3Ug!6g#oMuS;~> eGfNmo)Jd7JcF4!!+pc^JH3Ug!6g#oMuS;~> eGfN:o)Jd7JcF0uUW`b,!;anAAhu5Tm*#HtrlbC!RISK$B)'RPAhu5To#q,HRJ4o1Ahu5Tbfg&C o?7;K1G`Y3bQDH51M3u;JcCW-J,~> eGfN:o)Jd7JcF4!!6fuoJH3Ug!6g#oMuS;~> eGfN:o)Jd7JcF4!!6fuoJH3Ug!6g#oMuS;~> eGfM\o)O@AdJorb!&L.h!1A_gJcCW-J,~> eGfM\o)O@AdJj2&JH16$`;fn^JcCZ.J,~> eGfM\o)O@AdJj2&JH16$`;fn^JcCZ.J,~> eGfN:oDekIJcF*sJ]r\h`QWo5MZ82~> eGfN:oDekIJcF-t!+pc^JH3Xh!6g#oMuS;~> eGfN:oDekIJcF-t!+pc^JH3Xh!6g#oMuS;~> eGfM\oDem8JcF*sJ]r\h`QWo5MZ82~> eGfM\oDem8JcF-t!6fuoJH3Xh!6g#oMuS;~> eGfM\oDem8JcF-t!6fuoJH3Xh!6g#oMuS;~> eGfN:o`+u[JcF'rJ]r\h`QWo5MZ82~> eGfN:o`+u[JcF'r!&K0+JH3[i!6g#oMuS;~> eGfN:o`+u[JcF'r!&K0+JH3[i!6g#oMuS;~> eGfNmpAb5+b^of=s+/CFbf7kXs,-i,~> eGfNmpAb5+b^of>rrAI eGfNmpAb5+b^of>rrAI e,KD(r;cjR!bRkEJcC<$JcC<$JcD/ e,KD(r;cjR!bRkEJcC<$JcC<$JcD/ e,KD(r;cjR!bRkEJcC<$JcC<$JcD/ JcC<$JcC<$JcC<$iW"E~> JcC<$JcC<$JcC<$iW"E~> JcC<$JcC<$JcC<$iW"E~> JcC<$JcC<$JcC<$iW"E~> JcC<$JcC<$JcC<$iW"E~> JcC<$JcC<$JcC<$iW"E~> %%EndData showpage %%Trailer end %%EOF yaws-2.0.2/doc/b.eps0000664000175000017500000110346712605311412011127 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: /home/klacke/yaws/yaws/doc/b.eps %%Creator: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) - by John Bradley %%BoundingBox: -24 286 639 506 %%Pages: 1 %%DocumentFonts: %%EndComments %%EndProlog %%Page: 1 1 % remember original state /origstate save def % build a temporary dictionary 20 dict begin % define string to hold a scanline's worth of data /pix 663 string def % define space for color conversions /grays 663 string def % space for gray scale line /npixls 0 def /rgbindx 0 def % lower left corner -24 286 translate % size of image (on paper, in 1/72inch coords) 662.97600 220.03200 scale 663 220 8 % dimensions of data [663 0 0 -220 0 220] % mapping matrix {currentfile pix readhexstring pop} image 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000 00ffffffffffffffffffffffffffffffffffffffffffffff74ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff74ffffffffffffffffffff ffffffffffffffffffffffffff7400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 00ffe9e9e974747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474ffe9e9e97400 00ffe9e9e974ffffffffffffffffffffffffffffffffffff74ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffff74ffffffffffffffffffffffff ffffffffffff74ffffffffffffffffffffffffffffffffffff74ffffffffffffffffffff ffffffffffffffff74ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9ffffffe9e9e9e9 e9e9ffffffe9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e9e9e9e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e90202e90202e90202 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9ffffffffffffffffffff74e9e9e974ffe9e9ffe9e974e9e9e9 e9ffe9e974e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e9e9e9e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e90202e90202 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9ffe9e9e974e9e9 ffe9e9e974e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9020202e9e9e9020202e9e902020202e9e90202020202e90202e90202e90202 e9e902020202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9ffe9e9e974ff e9e9e974e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9ffffffffffffffffffff74e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9020202e9e9e9020202e90202e9e90202e9e9e9e90202e90202e90202e90202 e90202e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9ffffffff74 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9ffe9e9e9e9 e9e974e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e902020202e902020202e90202e9e90202e9e9e90202e9e90202e90202e90202 e9e9e9e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9ffe9e9e974 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9e9ffe9e9e9 e974e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e902e902e90202e90202e9e90202e9e9e902e9e9e90202e90202e90202 e9e90202020202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9ffe9e9e974 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9e9ffe9e9e9 e974e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e97474747474747474747474e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e9020202e90202e90202e9e90202e9e90202e9e9e90202e90202e90202 e90202e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9ffe9e9e974 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9ffe9e9e9e9 e9e974e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e9e902e9e90202e90202e9e90202e90202e9e9e9e90202e90202e90202 e90202e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e97474747474 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9ffe9e9e97474 e9e9e974e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e9e902e9e90202e9e902020202e9e90202020202e90202e90202e90202 e9e9020202e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9ffe9e9e974e9e9 74e9e9e974e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9ffe9e974e9e9e9 e974e9e974e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e97474747474747474747474e9e9e974ffe9e9ff7474e9e9e9e9 e9e9747474e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e974ffe9e9e97400 007474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747400 00ffffffff749c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9cffffffffff7400 00ffe9e9e9749cffffffffffffffffff9cffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e09cffffe9e9e97400 00ffe9e9e9749cffe03a3a3a3a3a80e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0000000000000000000000000000000000000000000000000000000000000000000 0000000000e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03a7575ffe0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff9c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e03affe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0a983e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e081577e e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e075e075e075e075e075e083e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0a9a957e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0818143 7ee0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0757575 75757575753ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e083e0aae0aae0aae0aae075e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4f5d4f5d4f5d4f5d4a2e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878787878787878787878787777777777777777777777777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0a9a9d44383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9d4 437ee0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c375aa 75aa757523173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e03ae075e0aae03ae03ae0e0e0e0e003e003e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f5d4f5d4f5d4f5d4f5a2e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878787878787878787878787777777777777777777777777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0a9a9d4814325e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9d4a9 d4437ee0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3aaaaaa aaaa75232323173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e02fe02fe003e0aae03ae075e03ae0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f5f5f5e0d4e0d4f5f5a2e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878787878787878787878787777777777777777777777777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0a9a9d4a9d4432583e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9d4 a9d4437ee0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4d4d4aad4aa d4aad4aaaaaa7523233ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e02fe058e02fe003e0e0e075e02fe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f5e0e0f5e0f5f5f5d475e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878787878787878787878787777777777777777777777777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 a9a9d4a9d481432357e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9d4a9 d4a9d4437ee0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4aad4aad4 aad4aad4aa2323233a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e03ae0e0e058e058e03ae0aae075e02fe0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f5e0f5e0f5e0f5f5f5753a3a75aa3a e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07878787878809f9f9e9e9e9e9e9e9e9f9d9d9d9d9d9d9d957d7777777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9 a9d4a9d4a9d443232383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e08181818181a9d4 a9d4a9d44343e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4aad4aa d4aad4aa233a17173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e07fe058e02fe003e0e0e03ae058e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 00e0ffe0ffffffffffffffffffffffffffffff9ce0e0e0e0e0ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff9ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4d4d4d4d4d4d4d4d4753a75aa3ae0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787897dccccccccccccccccccbcbcbcbcbcbcbcfd7d3a077777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9 d4a9d4a9d481d481d425e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9a9a9a9d4a9 d4a9d4a9d45743e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4d4d4 d4d475233a1717173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07fe02fe003e0aae075e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4d4f5d4f5d4f5d4f5a23a75aa3ae0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07878787878a4ce787878787878787878777777777777777ca3d7a4777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9d4 a9d4a9d481d481d4815725e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9a9a9d4a9d4 a9d4a9d4a9d45743e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4d4 d475233a171717173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e03ae075e0aae023e023e0aae0e0e03ae03ae0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0e0f7e0f7e0f7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0aad4f5d4f5d4f5d4f5d4a2753a3ae0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07878787878b2ca967f7878909596969277777b9d9d9d9d8d779dd7837777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9d4a9 d4a9d481d481d481d42323e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9a9a9a981a9 d4a9d4a9d4a9d45743e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4 75233a75171717173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0aae0e0e003e003e083e0aae075e075e03ae0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffff6d6d6d6dffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0f7e0f7e0f7e0f7e0f7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07575aaaaaa757575757575757575753a3a75e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07878787878c0dbdd897879d5dcdbdcc978788ddcd4d4dba97779d0a17777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e081a9a9a9 a9a981a981a981a9812323e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9a9a9818181 a981a9818181814357e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c375 233ae075171717173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e091e03ae023e03ae0e0e075e03ae0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffff6d6d6d75ffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0f7e0f7f7f7f7f7f7f7e0f7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075e0e0d4d4e0d4aaaa757575aaaa753a3a7575e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe078787878787a97da7d7880dc917ab9bb787899d67b7ad69b7777c1af7777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0437e7e 7e7e7e7e7e7e7e7e7e2325e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9d47e7e7e7e7e 7e7e7e7e7e7e252557e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e03a3a 3ae0e075171717233a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e091e03ae023e0aae075e03ae0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffa8d3ff6d6d6d75ffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0f7f7f7f7f7f7f7e0d7d7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075d4d4d4d4d4e0e0e0e0d4aa75753a3a753a75e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878a3d178788ddc8278c6ac7878a8ca7882db8d7777caa57777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0437e 437e437e43434343432325e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9437e437e43 4343434343252557e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e075171717233a3ae083e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e003e091e03ae003e0e0e03ae03ae0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffa8f76d6d6d6d3ad3ff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0f7f7f7f7d7f7f7f7d7d7e0f7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075d4aad4d4d4d4d4d4d4d4d4d4d43a3a3a75753a 9be0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878b0c378789bd77978d39f7878b6bb788fdb80777ad5977777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e043 7e437e4343434343432557e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e081d47e437e4343 43434343252557e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4d4d4d4d4d4 d4d4d4aaaa1723233a3ae08383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0aae0e0e03ae03ae03ae0aae07de03ae003e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffd3d3d76d6d6d6d2277a8 ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff00ffffffff00ff00ffffffffffffffffffffffffffffffffffffffffffff00ffff 00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0f7c0c0c0c0d7d7d7f7d7e0f7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075d4aaaaaaaaaaaaaaaaaaaaaaaa3a3a3a753a33 3a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878beb57878a8ca787edb917878c3ae789cd3797782db8a7777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 437e437e43434343432583e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e08181437e437e43 434343252557e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4aaaaaaaaaa aaaaaaaa752317233a3a838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e03ae075e0aae003e003e0aae0e0e07de003e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffa8f7d36d6d6d7577d7d3 75ffffffffffffffff00ffffffffffff00ffffff00ffffffffffffffffffffffffffffff ffff00ffffffff00ffff00ffffffffffffffffffffffffffffffffffffffffffff00ffff 00ffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff000000ffffff ff000000ffffffff000000ffffffff000000ffffffffff00ffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0a875757575a8d7d7d7f7f7e0f7e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075d4aaaacdaacdaacdaacdaaaaaa3a3a753a3a33 3a9be0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878cca77878b7bd788bdd837879d1a078aac8787790d97d7777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0437e43434323232323e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0000000 00000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e043252525257e43 434325255783838383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e000000000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4aaaaaaaaaa aaaaaaaa752323233a3a7575e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e03ae0e0e023e023e003e0aae075e003e03ae0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffa8f7d76d6d6d6d3af7d775 ffffffffffffffffff00ffffffffffff00ffffff00ffffffffffffffffffffffffffffff ffff00ffffffff00ffff00ffffffffffffffffffffffffffffffffffffffffffff00ffff 00ffffffffffffffffffffffffffffffffffffff00ffffffffffffffff00ffffff00ffff 00ffffff00ffff00ffffff00ffff00ffffff00ffffffff00ffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e075a8d3757522a8d7f7f7f7f7e0e0e0e00000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07575aacdaacdaacdaacdaa9bcdaa3a3a3a3a333a 9be0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000000000e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe078787878787bd7997878c5ae7898d77b787dda9278b8b978779ed1787777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e083 8383437e43432525255783838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000 000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0437e43 43253a5783838383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e00000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4aa75aa75aa 75aa75aa7575233a753a7583e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e003e03ae023e003e0e0e083e03ae0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffd3f7d7d36d6d6d6d75d7d322 ffffffffffffffffff00000000ffff0000000000000000ff00000000ffffffff00ffffff ff00ffffffff00ffffff00ffffff000000ffffffff000000ffffff000000ffffff00ffff 00000000ffffffff000000ffffffff000000ff00000000ffff00ffffff00ffffff00ffff 00ffffff00ffff00ffffff00ffff00ffffff00ffffff00ffffffff000000ffffffffffff ffe0ffe0ffe0e0e000000000000000e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 75a8d3a875753a22c0d7f7d7e0f7e0e0e00000e0e0e0e0e0e0e000000000e0e0e0e00000 0000e0e0e00000e00000e0e000000000e0e00000000000e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09b9b757575757575757575aaaa3a3a3a333a9b e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000000000e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787882dd8b7879d2a078a6cd787889db8578c5ac7877abc4777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 838383257e43252583838383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000 0000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0838383437e43 253a578383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0aa75757575 75757575757575753a758383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e03ae023e023e0aae075e03ae083e083e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffa8f7d7d36d6d6d7577d77575 ffffffffffffffffff00ffffff00ffff00ffffff00ffffff00ffffff00ffffff00ffffff ff00ffffffff00ffffff00ffff00ffffff00ffff00ffffff00ffffffffff00ffff00ffff 00ffffff00ffff00ffffff00ffff00ffffffffff00ffffffff00ffffffff000000ffffff 00ffffff00ffffff000000ffffff00ffffff00ffffff00ffffffffffffff00ffffffffff ffe0ffe0ffe0e0e0e00000000000e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e03a3ae0 227575753a3a753ac0f7d7f7f7e0e0e0e00000000000e0e0e00000e0e00000e0e0e0e0e0 e00000e0e00000000000e00000e0e0e0e0e00000e0e00000e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09b9b75753a3a3a3a3a33333a9be0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0000000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797992dc80797edc9479b6bf797897d97b78d39f7878bab7787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e08383257e2525838383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 00e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e08383434325 3a57838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0aa75753a 3a3a3a3a173a3a3a758383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e0aae023e023e0aae0aae023e07de083e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffa8f7d7d36d6d226d75d3d722ff ffffffffffffffffff00ffffff00ffff00ffffff00ffffff00ffffff00ffffffffffffff ff00ffffffff00ffffff00ffff00ffffff00ffff00ffffffffffff00000000ffff00ffff 00ffffff00ffff00ffffff00ffff0000ffffffff00ffffffffffffffff00ffffff00ffff 00ffffff00ffff00ffffff00ffff00ffffff00ffffff00ffffffff00000000ffffffffff ffe0ffe0ffe0e0e0e0e0000000e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e022c07575 d3c03a3a3a3a753ac0d7d7e0f7e0e0e0e0e00000000000e0e0000000000000e0e0e00000 000000e0e00000e0e0e0e00000e0e0e0e0e00000e0e00000e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09b3a333ae0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe079797979799fd47a798add8579c3b27978a5ce787fdb917878c8a9787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e08383252583838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e08383253a 57e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e083 83838383838383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e03ae075e075e075e075e083e083e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffa8d3d7d3f76d22d76d75d7757777 ffffffffffffffffff00ffffff00ffff00ffffff00ffffff00ffffff00ffffffffffffff 00ffffffff00ffffffff00ffff00ffffff00ffff00ffffffffff00ffffff00ffff00ffff 00ffffff00ffff00ffffff00ffffffff0000ffff00ffffffffffffffff00ffffff00ffff 00ffffff00ffff00ffffff00ffff00ffffff00ffff00ffffffff00ffffff00ffffffffff ffe0ffe0ffe0e0e0e0e0e000e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e07575a8d3 d3a83a223a223a75c0f7e0f7e0f7e0e0e0e0e0e0e00000e0e00000e0e0e0e0e0e00000e0 e00000e0e00000e0e0e0e00000e0e0e0e0e00000e0e00000e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07979797979adc8797998da7c79d0a37978b3c0788bdd83787ad49c787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffff77a8d36d22d7d76d22d3227575 7777ffffffffffffff00ffffff00ffff00ffffff00ffffff00ffffff00ffffff00ffffff 00ffffffff00ffffffff00ffff00ffffff00ffff00ffffff00ff00ffffff00ffff00ffff 00ffffff00ffff00ffffff00ffffffffff00ffff00ffffffff00ffffff00ffffff00ffff 00ffffff00ffff00ffffff00ffff00ffffff00ffff00ffffffff00ffffff00ffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e075a8d3d3a8 75753a22223a7580f7e0f7e0f7e0e0e0e000e0e0e00000e0e00000e0e0e000e0e00000e0 e00000e0e00000e0e0e0e00000e0e0e0e0e00000e0e00000e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07979797979bbb97979a6ce797ddb967978c0b27899d77b7880db8e787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffff22a8d3d3d7d3d7d322757575 7777ffffffffffffff00ffffff00ffffff0000ffff0000ff00000000ffffffff00ffff00 ffffffff00ffffffffff00ffffff000000ffffffff000000ffffff00000000ffff00ffff 00ffffff00ffffff000000ffffff000000ffffffff0000ffff00ffffffff000000ffffff ff000000ffffffff000000ffffffff000000ffff00ffffffffffff00000000ffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e07575d3d3a87575 753a2275808080e0e0a880a880a8e0e0e0e000000000e0e0e0e000000000e0e0e0e00000 000000e0e00000e0e0e0e0e000000000e0e00000e0e00000e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07979797979caab7979b4c17988de877979cea378a7cc78788edb81787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 00e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffff7722a8a8d7d3a822757777 ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff00 ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e075a8d3a87575753a 2275e0e0e0e0e0a8758080808080e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797ad59e7979c1b37995da7d797cda9778b5be78789ad579787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000000000e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0 00e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0babababae0e0e0bae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffff7722a8a8227777ffff ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e03a3a7575753a2275 e0e0e0e0a87575757575758080a8e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07979797981dd907979cfa579a4d1797986dc8978c2b07878a9c978787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0 00e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0bae0e0e0e0bae0e0bae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffff77227777ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0753a3a753a758080 e0a8807575758080a8e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979798edd83797cda9779b2c2797994db7d78d0a27878b7ba78787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0 e0e0000000e0e0e0e0000000e0e000e0e00000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0000000e0e0e000e00000e000 e0e000e0e000e0e0e0000000e0e0e000e00000e0e000000000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e0e0000000e0e0e0 00e0e0e0000000e0e0e0e0000000e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0bae0e0e0e0e0e0babababae0e0bababae0e0e0babababae0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0a8223a2280808080 808080a8e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979799cd87b7988de8979c0b67979a2d1797edb957979c7ae78787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e00000000000e0e0 e0e0e0e0e000e0e000e0e0e000e000e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e000e0e0e000e0e00000e0e0e000 e0e000e0e000e0e0e0e0e0e000e0e00000e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e000e0e0e000e0e0 00e0e000e0e0e000e0e0e0e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0babae0e0e0e0e0bae0e0e0bae0e0e0bae0e0bae0e0e0bae0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e000e00000e000e0e000000000e0e0 00000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe079797979abcc797994db7d79cda77979b0c57988de87797ad3a078787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0 e0e000000000e0e000e0e0e0e0e000e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e000e0e0e000e0e000e0e0e0e000 e000e000e000e0e0e000000000e0e000e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0e0e00000000000e0e0 00e0e000e0e0e000e0e0e000000000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0babae0e0e0bae0e0e0bae0e0e0bae0e0bae0e0e0bae0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e00000e0e0e000e0e000e0e0e000e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe079797979b8d9c8c8d0d37a7cd9d0c8c8d6b77996dec9c7c8dd9378787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0 e000e0e0e000e0e000e0e0e0e0e0000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e000e0e0e000e0e000e0e0e0e000 e000e000e000e0e000e0e0e000e0e000e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e000e0e0e0e000e0e0e0e0e0e0 00e0e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0bae0e0bae0e0e0bae0e0e0bae0e0bae0e0e0bae0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffe09c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9ce0e0e0e0e0ff9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0e000e0e0e0e000e0e000e0e0e000e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979799faeaeaeaea1797daeaeaeaeae93798eaeaeaeaead8078787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e000e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e000e0e0e000e0e000e0e0e0e0e0 00e0e0e000e0e0e000e0e0e000e0e000e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e000e0e0e000e0e0 00e0e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0bae0e0e0e0bae0e0bae0e0e0bae0e0e0bae0e0bae0e0e0bae0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e000e0e0e0e000e0e000e0e0e000e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797979797979797979797979797979797979797979787878787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e00000000000e0e0 e0e000000000e0e0e0000000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0000000e0e0e000e0e0e0e0e0 00e0e0e000e0e0e0e000000000e0e000e0e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0e0e0000000e0e0e0 00e0e0e0000000e0e0e0e000000000e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0babababae0e0e0e0babae0e0bababae0e0e0babababae0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e000e0e0e0e000e0e000e0e0e000e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797979797979797979797979797979797979797979787878787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0bae0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e000e0e0e0e000e0e000e0e0e000e0 e0e00000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797979797979797979797979797979797979797979787878787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0bae0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797979797979797979797979797979797979797979787878787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0000000000000000000000000000000000000000000000000000000000000000000 0000000000e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e09cffffe9e9e97400 00ffe9e9e9749cff9c9c9c9c9c9c9c9c9cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9cffffe9e9e97400 00ffe9e9e9749cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffff9cffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffff9ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0 ffe0e0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0ffe0 e0e0e0e0ffe0e0e0e0e0ffe0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0ffe0e0e03ae0ffe0e0e03ae0ffe0e0e03ae0ffe0e0 e03ae0ffe0e0e03ae0e09cffe0e03ae0e0e0e0ffe0e0e03ae0ffe0e0e03ae0ffe0e0e03a e0ffe0e0e03ae0ffe0e0e03ae0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e03a3ae0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0 e0e0e0e03ae0e0e0e0e09cffe0e03a3ae0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0e0e0 e0e03ae0e0e0e0e03ae0e0e0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e03a753ae0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0 ffe0e0e0e0e0ffe0e0e09cffe0e03a753ae0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0ffe0 e0e0e0e0ffe0e0e0e0e0ffe0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e03a75ffe0e0ffe0e0e03ae0ffe0e0e03ae0ffe0e0e03ae0ffe0e0 e03ae0ffe0e0e03ae0e09cffe0e03a75ffe0e0ffe0e0e03ae0ffe0e0e03ae0ffe0e0e03a e0ffe0e0e03ae0ffe0e0e03ae0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e03affe0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0 e0e0e0e03ae0e0e0e0e09cffe0e03affe0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0e0e0 e0e03ae0e0e0e0e03ae0e0e0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9cffffe9e9e97400 00ffe9e9e974000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000ffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffff0000ffffffffffffffffffffff ffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffffffffff ffffffffffffffffffffffff00000000ffff000000ffff0000000000ffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffff000000ffffffffffffffffffff ffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffff ffffffffffffffffffffff0000ffff0000ff000000ffffffff000000ffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffff00000000ffffffffffffffffffff ffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffff ffffffffffffffffffff000000ffff0000ff000000ffffffff000000ffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffff0000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffff ffffffffffffffffffff000000ffffffffffffffffffffffff000000ffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffff00ff000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffff ffffffffffffffffffff000000ffffffffffffffffffffffff000000ffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffff0000ff000000ffffffffffffffffff ffffffffffffff0000000000ffffff00000000ffffff00000000ffff00000000ffffff00 000000ffffffff00000000ffff000000ffffffffffff000000ffffffffffff0000000000 ffffffffffffffffff000000000000ffff00000000ffffffff000000ffffffffffff0000 000000ffffffffffffffffff00000000ffffff00000000ffffff00000000ffff000000ff ffffffffff000000ffffffffffff0000000000ffffffffffffff0000000000ffffffffff ffffff00000000ff000000ffffffffffffffffff00000000ffff000000ffffffffffffff 0000000000ffffffffffffff0000000000ffffffffffffffff0000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffff0000ffff000000ffffffffffffffff ffffffffffff0000ffff0000ffffffff000000ffffffff000000ff0000000000ff000000 00000000ffffffff000000ff000000000000ffffffff000000ffffffff000000ffff0000 00ffffffffffffffffff000000ffffffffff000000ffffffff000000ffffffff000000ff ff000000ffffffffffffffffff000000ffffffff000000ffffffff000000ff0000000000 00ffffffff000000ffffffff00000000ff00000000ffffffff0000ffff000000ffffffff ff00000000000000000000ffffffffffffffffffff000000ff000000000000ffffffff00 00ffff000000ffffffffff000000ff0000000000ffffff000000ffff000000ffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffff00ffffff000000ffffffffffffffff ffffffffff000000ffffff00ffffffff000000ffffffff00000000ffffff00000000ffff ff000000ffffffff0000000000ffff000000ffffffff000000ffffffff0000ffffff0000 00ffffffffffffffffff000000ffffffffff000000ffffffff000000ffffffff0000ffff ff000000ffffffffffffffffff000000ffffffff000000ffffffff0000000000ffff0000 00ffffffff000000ffffffff000000ffffff000000ffffff000000ffffff000000ffffff ff000000ffffff00000000ffffffffffffffffffff0000000000ffff000000ffffff0000 00ffffff000000ffffff000000ffffff000000ffffffff0000ffffff000000ffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffff0000ffffff000000ffffffffffffffff ffffffffff000000ffffff00ffffffff000000ffffffff000000ffffffff000000ffffff ff000000ffffffff00000000ffffffff000000ffffff000000ffffff000000ffffffff00 0000ffffffffffffffff000000ffffffffff000000ffffffff000000ffffff000000ffff ffff000000ffffffffffffffff000000ffffffff000000ffffffff00000000ffffffff00 0000ffffff000000ffffff000000ffffffffff000000ffff000000ffffff000000ffffff 000000ffffffffff000000ffffffffffffffffffff00000000ffffffff000000ffff0000 00ffffff000000ffffff000000ffffff000000ffffff000000ffffffff000000ffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffff00ffffffffff000000ffffffffffffff ffffffffff0000000000ffffffffffff000000ffffffff000000ffffffff000000ffffff ff000000ffffffff000000ffffffffff000000ffffff000000ffffff000000ffffffff00 0000ffffffffffffffff000000ffffffffff000000ffffffff000000ffffff000000ffff ffff000000ffffffffffffffff000000ffffffff000000ffffffff000000ffffffffff00 0000ffffff000000ffffff000000ffffffffff000000ffffff00ffffffff000000ffffff 000000ffffffffff000000ffffffffffffffffffff000000ffffffffff000000ffffff00 ffffffff000000ffffff000000ffffff000000ffffff000000ffffffff000000ffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffff00ffffffffff000000ffffffffffffff ffffffffffff0000000000ffffffffff000000ffffffff000000ffffffff000000ffffff ff000000ffffffff000000ffffffffff000000ffffff000000ffffff0000000000000000 0000ffffffffffffffff000000ffffffffff000000ffffffff000000ffffff0000000000 0000000000ffffffffffffffff000000ffffffff000000ffffffff000000ffffffffff00 0000ffffff000000ffffff000000ffffffffff000000ffffffffffff0000000000ffffff 000000ffffffffff000000ffffffffffffffffffff000000ffffffffff000000ffffffff ffff0000000000ffffff000000ffffff000000ffffff00000000000000000000ffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffff00000000000000000000ffffffffffffff ffffffffffffff0000000000ffffffff000000ffffffff000000ffffffff000000ffffff ff000000ffffffff000000ffffffffff000000ffffff000000ffffff000000ffffffffff ffffffffffffffffffff000000ffffffffff000000ffffffff000000ffffff000000ffff ffffffffffffffffffffffffff000000ffffffff000000ffffffff000000ffffffffff00 0000ffffff000000ffffff000000ffffffffff000000ffffff000000ffff000000ffffff 000000ffffffffff000000ffffffffffffffffffff000000ffffffffff000000ffffff00 0000ffff000000ffffffff000000ffff0000ffffffff000000ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffff00ffffffffffff00000000ffffffffffff ffffffffffffffff0000000000ffffff000000ffffffff000000ffffffff000000ffffff ff000000ffffffff000000ffffffffff000000ffffff000000ffffff000000ffffffffff ffffffffffffffffffff000000ffffffffff000000ffffffff000000ffffff000000ffff ffffffffffffffffffffffffff000000ffffffff000000ffffffff000000ffffffffff00 0000ffffff000000ffffff000000ffffffffff000000ffff000000ffffff000000ffffff 000000ffffffffff000000ffffffffffffffffffff000000ffffffffff000000ffff0000 00ffffff000000ffffffffff0000000000ffffffffff000000ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffff0000ffffffffffffff000000ffffffffffff ffffffffff00ffffffff000000ffffff000000ffffffff000000ffffffff000000ffffff ff000000ffffffff000000ffffffffff000000ffffff000000ffffff00000000ffffffff ffffffffffffffffffff000000ffffffffff000000ffffffff000000ffffff00000000ff ffffffffffffffffffffffffff000000ffffffff000000ffffffff000000ffffffffff00 0000ffffff000000ffffff000000ffffffffff000000ffff000000ffffff000000ffffff 00000000ffffffff000000ffffffffffffffffffff000000ffffffffff000000ffff0000 00ffffff000000ffffffff000000ffffffffffffffff00000000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffff0000ffffffffffffff00000000ffffffffff ffffffffff00ffffffff000000ffffff000000ffffffff000000ffffffff000000ffffff ff000000ffffffff00000000ffffff000000ffffffff000000ffffffff00000000ffffff 00ffffffffffffffffff000000ffffffffff000000ffffffff000000ffffffff00000000 ffffff00ffffffffffffffffff000000ffffff00000000ffffffff00000000ffffff0000 00ffffffff000000ffffffff000000ffffff000000ffffff000000ffff00000000ffffff ff000000ffffff00000000ffffffffffffffffffff00000000ffffff000000ffffff0000 00ffff00000000ffffff000000ffffffffffffffffffff00000000ffffff00ffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffff000000ffffffffffffff00000000ffffffffff ffffffffff0000ffffff0000ffffffff000000ffffffff000000ffffffff000000ffffff ff000000ffffffff000000ff000000000000ffffffff000000ffffffff00000000000000 ffffffffffffffffffff000000ffffffffff000000ffffffff000000ffffffff00000000 000000ffffffffffffffffffff000000000000ff00000000ffffff000000ff0000000000 00ffffffff000000ffffffff00000000ff00000000ffffff00000000000000000000ffff ff000000000000ff000000ffffffffffffffffffff000000ff000000000000ffffff0000 0000000000000000ffff000000000000000000ffffffff00000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffff0000000000ffffffff0000000000000000ffffff ffffffffff000000000000ffffffff0000000000ffff0000000000ffff0000000000ffff 0000000000ffffff000000ffff000000ffffffffff0000000000ffffffffff00000000ff ffffffffffffffffff0000000000ffffff0000000000ffff0000000000ffffffffff0000 0000ffffffffffffffffffffffff00000000ffff000000ffffffff000000ffff000000ff ffffffff0000000000ffffffffff0000000000ffffffffffff000000ffffff0000ffffff ffffff000000ffffff000000ffffffffffffffffff000000ffff000000ffffffffffff00 0000ffffff0000ffffff00000000000000000000ffffffffff00000000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffff ffffffffffffffffffffff000000000000000000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffff ffffffffffffffffffff000000ffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffff ffffffffffffffffffff0000ffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffff ffffffffffffffffffff0000ffffffffff0000ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffff ffffffffffffffffffffff00000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5ffffffff7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7cf5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f57cffffffff7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7cf5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f57cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffffffff00ff00ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff00ff00ffffffffffff00ffffffffffffffffffffffffff ffff00ffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffffff00ffff00ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff00ffff00ffffffffffff00ffffffffffffffffffffffffff ffff00ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e000e0e0e0e000e0e0e0e0 e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffffff00ffff00ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff00ffff00ffffffffffff00ffffffffffffffffffffffffff ffff00ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e000e0e0e0e000e0e0e0e0 e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffff00ffffff00000000ffffffff000000ffffff0000000000000000 ffffffff000000ffffffff00ffffff00ffff0000ffff00ffffff000000ffffffff000000 ffff00ffff0000ffffff000000ffffffff00ffffff00ffffff00ffffff000000ffffff00 ffff00ffff00ffffff000000ffffff00ffffff00ffffff00ffffff000000ffffff00ffff 00ffff00f5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e000e0e0e0e000e0e00000 0000e0e0e000e0e0e0000000e0e0e0e0000000e0e0e0e000000000e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffff00ffffff00ffffff00ffff00ffffff00ffff00ffffff00ffffff 00ffff00ffffff00ffffff00ffffff00ffff00ffffff00ffffffffffff00ffff00ffffff 00ff00ffff00ffffff00ffffff00ffffff00ffffffff00ff00ffffffffffffff00ffff00 ffff00ffff00ffff00ffffffffffff00ffffffff00ff00ffffffffffffff00ffff00ffff 00ffff00f5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e000e00000e0e00000 00e0e0e000e0e000e0e000e0e0e0000000e0e0e0000000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e000e0e0e0e000e0e000e0 e0e000e0e000e0e000e0e0e000e0e0e0e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffff00ffffff00ffffff00ffff00ffffff00ffff00ffffff00ffffff 00ffff0000000000ffffff00ffffff00ff00ffffffff00ffffff00000000ffff00ffffff ffff00ff00ffffffff0000000000ffffff00ffffffff00ff00ffffffff00000000ffff00 ff00ff00ff00ffff0000ffffffffff00ffffffff00ff00ffffffff00000000ffff00ff00 ff00ff00f5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e00000000000e0e0e00000e0e0e000e0e0 e000e0e000e0e000e0e000e0e000e0e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e000e0e0e0e000e0e000e0 e0e000e0e000e0e000e0e0e000e0e0e000000000e0e000e0e0e000e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cff00ffffffff00ffffff00ffff00ffffff00ffff00ffffff00ffffff 00ffff00ffffffffffff00ffffffff000000ffffffff00ffff00ffffff00ffff00ffffff ffff000000ffffffff00ffffffffffff00ffffffffff00ff00ffffff00ffffff00ffff00 ff00ff00ff00ffffffff0000ffff00ffffffffff00ff00ffffff00ffffff00ffff00ff00 ff00ff00f5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0e000e0e0e0e000e0e0 e000e0e000e000e000e000e0e00000e0e0e0e00000000000e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e000e0e0e0e000e0e000e0 e0e000e0e000e0e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cff00ffffffff00ffffff00ffff00ffffff00ffff00ffffff00ffffff 00ffff00ffffff00ffff00ffffffff00ffff00ffffff00ffff00ffffff00ffff00ffffff 00ff00ffff00ffffff00ffffff00ffff00ffffffffffff00ffffffff00ffffff00ffffff 00ffffff00ffffffffffff00ffff00ffffffffffff00ffffffff00ffffff00ffffff00ff ffff00fff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0e000e0e0e0e000e0e0 e000e0e000e000e000e000e0e0e0e00000e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e000e0e0e0e000e0e000e0 e0e000e0e000e0e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7c00ffffffffff00ffffff00ffffff000000ffffff00ffffff00ffffff 00ffffff000000ffff00ffffffffff00ffffff00ffff00ffffff00000000ffffff000000 ffff00ffffff00ffffff000000ffff00ffffffffffffff00ffffffffff00000000ffffff 00ffffff00ffffff000000ffff00ffffffffffffff00ffffffffff00000000ffffff00ff ffff00fff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0e000e0e0e0e000e0e0 e000e0e0e000e0e0e000e0e0e0e0e0e000e0e000e0e0e000e0e0e000e0e0e000e0e0e000 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e0e000000000e0e0e00000 0000e0e0e000e0e0e0000000e0e0e0e000000000e0e0e000000000e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7c00ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff00ffffffffffffff00ffffffffffffffffffffffff ffffffffffffffffffffffffff00ffffffffffffff00ffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e00000000000e0e0e000e0e0e0e0e00000 00e0e0e0e000e0e0e000e0e0e0000000e0e0e0e0000000e0e0e0e000e0e0e000e0e0e000 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 7c7cffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffff5f5f5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff5f57c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7cffffffff7c7cf5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f57c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00fffffffffffffffff57c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7cffffffff7cf5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f57c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7cffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0ffe9e9e97400 00ffe9e9e9749cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffff9cffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff9cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9cffffffff ffffffffffffffffffffffffffffffffffffffffffffff9cffffffffffffffffffffffff ffffffffff9cff9cffffe9e9e97400 0074747474749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cff747474747400 00ffffffff749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cffffffffff7400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0d73ae0e0e0d73a66e0e0d7a866e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a8a8a8a8a87575757575577557e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e09999e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0757575e0666666e0464646e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e06f6f 6f3a3a3ae09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0d73ad7f7ffd7d366d7a83ae0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e066ffff57ff27ff57a8ff75ff75e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0d3ffd3d3e000ff996d00e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e03a3a3a3a3a3a66666666464646463a66e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e04242424242424242e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0753a3ae0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e06fc0c3 8ac0c06f3a9cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0d7f73aff3ad7f7a83a66e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e06627ffffffffffff27ff57ff57e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0d3ffffffffffd300ff996d0000e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f7f7f7f7f7f7f7f7f7f7f73a66e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e042e9ffffffffff5fe0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0000000 0000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e00000000000e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0000000e0 e0e0e0e0e0e0e0000000e0e0e0e0000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e075ffd33a75753ae0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e06f6fc0 002c6fc33a9cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0d7f7a83ad73aa8d7f766e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e066ffff664cffffffa8ff27ff27e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0d3ffffffffd3ffd3d7cc996d000099e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f7f7f7f7f7753a75f7f7f73a66e0e0e0e0e0e0e0e0e0e0e0e0e0424242 42424297e86a42d4ffbf42e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e000 e0e0e0e0e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e075a8d327d3ffd33ae0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e03ac06f e0e025c33a9cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0d7a83aa8d7a8663ad73a6666e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e06657ff4c4cffffff57ff75ff75e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e03ad3ffd3d7d3d7d3d7d399cc000099e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af775757575f7f7f73a3a3af7f7f73a66e0e0e0e0e0e0e0e0e0e0e0e04280e8ff e88042af5f4295ffe85642e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e0e000e0e0e0000000e0e0e0e0000000e0e000e0e0e000e0e00000000000000000e0e0 e0e0000000e0e0e000000000e0e000000000e0e000e0e0e0e0e0e0e000e0e0e0e0e000e0 e0e0000000e0e0e000000000e0e0e0e0000000e0e0e0e0e0e0e000e0e0e0e000e0e0e000 e0e0e0e0e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0000000e0e0e0000000e0e0 e0e0000000e0e0e0000000e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e03a3aa8d327a8a8a83a3ae0e0e0e0e0e0e09cffe0e06f6f6f6f6f6f3ac06f 6fe06f00009cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e066d7f7f7f7f7f7f7f7f7d7f7d3f7d3d73ae0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e066ffffffffffffffa8ff57ff57e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0993ad3d7d3d7d3d7cc996d000099d3ffe0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f7f7f7f7f7753a75f7f7f73a66e0e0e0e0e0e0e0e0e0e0e0426affd442 d4ff42e0426affff6a42e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e0e000e0e000e0e0e000e0e000e0e0e000e000e0e0e000e0e000e0e0e000e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e0e000e0e0e0e0e0e0e000e0e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e000e0e0e0e000e0e0e000 e0e0e0e0e0e000e0e0e000e0e0e0000000e0e0e0e0e0e0e000e0e0e0e0e000e0e0e000e0 e000e0e0e000e000e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cff757575 757575757575d33aa8d327a8a8a83ad3003a3a3a3a3a3a9cffe06fc3006c6c6c6c6f6f6f 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0663a3ad7a83aa8d7a83a3ad73a3a3a66e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0666627ffff66f766ff27ff75ff75333333e0e0e0e0e0 e0e0e0e0e0e0e0e0e0993ad3d7d3d7cc996d0000d7d3d7d3ffe0e0e0e0e0e0e0e0e0e0e0 e0e0e03af775757575f7f73af7f7f73af7f73a66e0e0e0e0e0e0e0e0e0e0e042bfff8042 6ab4424256e8ff95424242e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e0e000e0e000e0e0e000e0e000e0e0e0e0e000e0e0e000e0e000e0e0e000e0e0e000e0 e00000000000e0e000e0e0e000e0e000e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e00000000000e0e0e0e0e0e000e0e0e0e000e0e0e000 e0e0e0e0e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e00000e0e0e0e00000000000e0 e000e0e0e0e0e00000e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffd3d3a8 d3a8a8a8a83aa83aa8d327a8a8a83aa83aa8a8a8a8a8a89cffe03ac38ac3c3c3c3c3c32c 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0d7d7a83ad73aa866d73a66ffa8a8a8a8 a8a8e0e0e0e0e0e0e0e0e0e0e021333affffffccf7ccffa8ff75ff75333333e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0993ad3d3cc996d0000d7d3d7d3d7d3ff00e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f7f7f73a3a3af73a3a3af73a66e0e0e0e0e0e0e0e0e0e0e042bfff8042 42564242bfffbf4242a980e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e0e000e0e000e0e0e000e0e000e0e0e0e0e000e0e0e000e0e000e0e0e000e0e0e000e0 e000e0e0e0e0e0e000e0e0e000e0e000e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0e0e000 e0e0e0e0e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e00000e0e000e0e0e0e0e0 e000e0e0e0e0e0e0e00000e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cff3a3a3a 3a3a3a3a3a3a753aa8d327a8a8a83a753a3a3a3a3a3a3a9cffe03ac3c34b4b4b4b4b2c6f 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e066d7d73af73ad3d73a3a75a875757566 a8e0e0e0e0e0e0e0e0e0e0e0e0757575757575757575757575757533333333e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0993acc99000000d7d3d7d3d7d30000e0e0e0e0e0e0e0e0e0e0 e0e0e03af775757575f73a3a3a3a3a3a3af73a66e0e0e0e0e0e0e0e0e0e0e0426affe856 6aff8280ffe85656a9ff58e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e000e0e0e000e0e0e000e0e000e0e0e000e000e0e0e000e0e000e0e0e000e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e0e000e0e0e0e0e0e0e000e0e0e0e000e0e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e000e0e0e0e000e0e0e000 e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e000e0e000e0e0e000e0 e000e0e0e000e0e0e0e000e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e03a3aa8d3277575753a3ae0e0e0e0e0e0e09cffe03ac38a6c6c6c6c6c6c2c 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e066d7ccd7d3f7d3d73ad73a6675666666a8 e0e0e0e0e0e0e0e0e0e0e0e0e075757575757575757575753a753a33333a66e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0d7a2d70000d7d3d7d3d70000d3e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f7f7f73a3a3a3a3a3a3af73a66e0e0e0e0e0e0e0e0e0e0e0e04284e8ff e8c942e8ffffffffffe242e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0000000 0000e0e0e0e0e0000000e0e0e0e0000000e0e0e000000000e0e000e0e0e000e0e0e000e0 e0e0000000e0e0e000e0e0e000e0e0e00000e0e000e0e0e0e0e0e0e00000000000e0e0e0 e0e0000000e0e0e000e0e0e000e0e0e0000000e0e0e0e0e0e0e0e000e0e0e0e0000000e0 e0e0e000e0e0e0000000e0e0e0e0000000e0e0e0e0e0e0e0000000e0e0e0e0000000e0e0 e0e0000000e0e0000000e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e03aa875277575753ae0e0e0e0e0e0e0e09cffe03ac3c34b4b4b4b4b2c6f 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0d7cc3a663ad73a3a3a75d73a666666a8a8 e0e0e0e0e0e0e0e0e0e0e0e0e075753a753a753a753a753a753a75333366e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0a2ffa2a299d3d7d30000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f766f7f7f7f7f766f7f7f73a66e0e0e0e0e0e0e0e0e0e0e0e0e0424242 4242424242424242424242e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e00075753a3a3a3ae0e0e0e0e0e0e0e0e09cffe03ac38a6c6c6c6c6c6c6f 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e03a66a8a8d73a7566e0e03a66a8e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e044a244e03a3a0000d3e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03a3a3a3a3ae03a3a3a3a3ae03a3a3a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e03a3a3ae0e0e0e0e0e0e0e0e0e0e0e09cffe06f3a2525252525250000 6fe0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9cff9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9cff9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9cff9cffffe9e9e97400 00ffe9e9e9749cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e974ffffffffffffffffffffffffffffffffffff74ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff74ffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 007474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747400 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000 showpage % stop using temporary dictionary end % restore original state origstate restore %%Trailer yaws-2.0.2/doc/layout.eps0000664000175000017500000002511612605311412012214 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: /home/klacke/yaws/yaws/doc/layout.dia %%Creator: Dia v0.88.1 %%CreationDate: Sat Nov 9 11:33:52 2002 %%For: klacke %%Magnification: 1.0000 %%Orientation: Portrait %%BoundingBox: 0 0 478 508 %%Pages: 1 %%BeginSetup %%EndSetup %%EndComments %%BeginProlog [ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def /Times-Roman-latin1 /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Times-Italic-latin1 /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Times-Bold-latin1 /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Times-BoldItalic-latin1 /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-Book-latin1 /AvantGarde-Book findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-BookOblique-latin1 /AvantGarde-BookOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-Demi-latin1 /AvantGarde-Demi findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-DemiOblique-latin1 /AvantGarde-DemiOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-Light-latin1 /Bookman-Light findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-LightItalic-latin1 /Bookman-LightItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-Demi-latin1 /Bookman-Demi findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-DemiItalic-latin1 /Bookman-DemiItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-latin1 /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-Oblique-latin1 /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-Bold-latin1 /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-BoldOblique-latin1 /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-latin1 /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Oblique-latin1 /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Bold-latin1 /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-BoldOblique-latin1 /Helvetica-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-latin1 /Helvetica-Narrow findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-Oblique-latin1 /Helvetica-Narrow-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-Bold-latin1 /Helvetica-Narrow-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-BoldOblique-latin1 /Helvetica-Narrow-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-Roman-latin1 /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-Italic-latin1 /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-Bold-latin1 /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-BoldItalic-latin1 /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Symbol-latin1 /Symbol findfont definefont pop /ZapfChancery-MediumItalic-latin1 /ZapfChancery-MediumItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /ZapfDingbats-latin1 /ZapfDingbats findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /cp {closepath} bind def /c {curveto} bind def /f {fill} bind def /a {arc} bind def /ef {eofill} bind def /ex {exch} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth pop} bind def /tr {translate} bind def /ellipsedict 8 dict def ellipsedict /mtrx matrix put /ellipse { ellipsedict begin /endangle exch def /startangle exch def /yrad exch def /xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def x y tr xrad yrad sc 0 0 1 startangle endangle arc savematrix setmatrix end } def /mergeprocs { dup length 3 -1 roll dup length dup 5 1 roll 3 -1 roll add array cvx dup 3 -1 roll 0 exch putinterval dup 4 2 roll putinterval } bind def 28.346000 -28.346000 scale -3.700000 -19.050000 translate %%EndProlog 1.000000 1.000000 1.000000 srgb n 3.800000 1.200000 m 3.800000 19.000000 l 20.500000 19.000000 l 20.500000 1.200000 l f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 3.800000 1.200000 m 3.800000 19.000000 l 20.500000 19.000000 l 20.500000 1.200000 l cp s 0.100000 slw [] 0 sd [] 0 sd 0 slc n 3.750000 4.200000 m 20.300000 4.200000 l s 0.100000 slw [] 0 sd [] 0 sd 0 slc n 3.850000 7.450000 m 20.450000 7.500000 l s 0.100000 slw [] 0 sd [] 0 sd 0 slc n 3.850000 10.850000 m 20.450000 10.800000 l s 0.100000 slw [] 0 sd [] 0 sd 0 slc n 3.850000 14.800000 m 20.350000 14.800000 l s /Courier-Bold-latin1 ff 0.800000 scf sf (100 bytes of HTML code) dup sw 2 div 11.100000 ex sub 2.800000 m gs 1 -1 sc sh gr /Courier-Bold-latin1 ff 0.800000 scf sf (120 bytes of Erlang code) dup sw 2 div 11.300000 ex sub 5.850000 m gs 1 -1 sc sh gr /Courier-Bold-latin1 ff 0.800000 scf sf (80 bytes of HTML code) dup sw 2 div 10.900000 ex sub 9.350000 m gs 1 -1 sc sh gr /Courier-Bold-latin1 ff 0.800000 scf sf (60 bytes of Erlang code) dup sw 2 div 11.150000 ex sub 13.000000 m gs 1 -1 sc sh gr /Courier-Bold-latin1 ff 0.800000 scf sf (140 bytes of HTML code) dup sw 2 div 10.950000 ex sub 16.950000 m gs 1 -1 sc sh gr showpage yaws-2.0.2/doc/overview.edoc0000664000175000017500000000126412605311412012666 00000000000000@title Yaws -An Erlang Web Server @doc

This is a very rough import of Yaws into Erlware. In particular -disable-pam was used to create the configure script. It is uncertain what the effects of this are. Also some modules was not included in the yaws.app file and may therefore not be compiled.

They were: ymnesia, yaws_showarg, yaws_vdir, yaws_content_negotiation It is unclear if they were intentionally left out or not.

Finally some files, that normally is generated at build time was included already generated. They were: mime_types.erl, yaws_generated.erl.

@author Torbjorn Tornkvist @copyright 2008 Torbjorn Tornkvist yaws-2.0.2/doc/a.eps0000664000175000017500000110346712605311412011126 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: /home/klacke/yaws/yaws/doc/a.eps %%Creator: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) - by John Bradley %%BoundingBox: -24 286 639 506 %%Pages: 1 %%DocumentFonts: %%EndComments %%EndProlog %%Page: 1 1 % remember original state /origstate save def % build a temporary dictionary 20 dict begin % define string to hold a scanline's worth of data /pix 663 string def % define space for color conversions /grays 663 string def % space for gray scale line /npixls 0 def /rgbindx 0 def % lower left corner -24 286 translate % size of image (on paper, in 1/72inch coords) 662.97600 220.03200 scale 663 220 8 % dimensions of data [663 0 0 -220 0 220] % mapping matrix {currentfile pix readhexstring pop} image 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000 00ffffffffffffffffffffffffffffffffffffffffffffff74ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff74ffffffffffffffffffff ffffffffffffffffffffffffff7400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 00ffe9e9e974747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474ffe9e9e97400 00ffe9e9e974ffffffffffffffffffffffffffffffffffff74ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffff74ffffffffffffffffffffffff ffffffffffff74ffffffffffffffffffffffffffffffffffff74ffffffffffffffffffff ffffffffffffffff74ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9ffffffe9e9e9e9 e9e9ffffffe9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e9e9e9e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e90202e90202e90202 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9ffffffffffffffffffff74e9e9e974ffe9e9ffe9e974e9e9e9 e9ffe9e974e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e9e9e9e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e90202e90202 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9ffe9e9e974e9e9 ffe9e9e974e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9020202e9e9e9020202e9e902020202e9e90202020202e90202e90202e90202 e9e902020202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9ffe9e9e974ff e9e9e974e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9ffffffffffffffffffff74e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9020202e9e9e9020202e90202e9e90202e9e9e9e90202e90202e90202e90202 e90202e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9ffffffff74 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9ffe9e9e9e9 e9e974e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e902020202e902020202e90202e9e90202e9e9e90202e9e90202e90202e90202 e9e9e9e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9ffe9e9e974 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9e9ffe9e9e9 e974e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e902e902e90202e90202e9e90202e9e9e902e9e9e90202e90202e90202 e9e90202020202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9ffe9e9e974 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9e9ffe9e9e9 e974e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e97474747474747474747474e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e9020202e90202e90202e9e90202e9e90202e9e9e90202e90202e90202 e90202e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9ffe9e9e974 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9e9ffe9e9e9e9 e9e974e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e9e902e9e90202e90202e9e90202e90202e9e9e9e90202e90202e90202 e90202e9e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e97474747474 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9e9ffe9e9e97474 e9e9e974e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e90202e9e902e9e90202e9e902020202e9e90202020202e90202e90202e90202 e9e9020202e90202e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9ffe9e9e974e9e9 74e9e9e974e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9ffe9e9e9e9e9e9e9e9e974e9e9e974ffe9e9ffe9e974e9e9e9 e974e9e974e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e97474747474747474747474e9e9e974ffe9e9ff7474e9e9e9e9 e9e9747474e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e974ffe9e9e97400 00ffe9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e974ffe9e9e97400 007474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747400 00ffffffff749c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9cffffffffff7400 00ffe9e9e9749cffffffffffffffffff9cffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e09cffffe9e9e97400 00ffe9e9e9749cffe03a3a3a3a3a80e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0000000000000000000000000000000000000000000000000000000000000000000 0000000000e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03a7575ffe0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff9c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e03affe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0a983e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e081577e e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e075e075e075e075e075e083e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0a9a957e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0818143 7ee0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0757575 75757575753ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e083e0aae0aae0aae0aae075e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4f5d4f5d4f5d4f5d4a2e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878787878787878787878787777777777777777777777777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0a9a9d44383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9d4 437ee0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c375aa 75aa757523173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e03ae075e0aae03ae03ae0e0e0e0e003e003e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f5d4f5d4f5d4f5d4f5a2e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878787878787878787878787777777777777777777777777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0a9a9d4814325e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9d4a9 d4437ee0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3aaaaaa aaaa75232323173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e02fe02fe003e0aae03ae075e03ae0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f5f5f5e0d4e0d4f5f5a2e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878787878787878787878787777777777777777777777777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0a9a9d4a9d4432583e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9d4 a9d4437ee0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4d4d4aad4aa d4aad4aaaaaa7523233ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e02fe058e02fe003e0e0e075e02fe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f5e0e0f5e0f5f5f5d475e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878787878787878787878787777777777777777777777777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 a9a9d4a9d481432357e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9d4a9 d4a9d4437ee0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4aad4aad4 aad4aad4aa2323233a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e03ae0e0e058e058e03ae0aae075e02fe0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f5e0f5e0f5e0f5f5f5753a3a75aa3a e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07878787878809f9f9e9e9e9e9e9e9e9f9d9d9d9d9d9d9d957d7777777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9 a9d4a9d4a9d443232383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e08181818181a9d4 a9d4a9d44343e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4aad4aa d4aad4aa233a17173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e07fe058e02fe003e0e0e03ae058e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 00e0ffe0ffffffffffffffffffffffffffffff9ce0e0e0e0e0ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff9ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4d4d4d4d4d4d4d4d4753a75aa3ae0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787897dccccccccccccccccccbcbcbcbcbcbcbcfd7d3a077777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9 d4a9d4a9d481d481d425e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9a9a9a9d4a9 d4a9d4a9d45743e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4d4d4 d4d475233a1717173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e07fe02fe003e0aae075e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4d4f5d4f5d4f5d4f5a23a75aa3ae0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07878787878a4ce787878787878787878777777777777777ca3d7a4777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9d4 a9d4a9d481d481d4815725e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9a9a9d4a9d4 a9d4a9d4a9d45743e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4d4 d475233a171717173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e03ae075e0aae023e023e0aae0e0e03ae03ae0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0e0f7e0f7e0f7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0aad4f5d4f5d4f5d4f5d4a2753a3ae0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07878787878b2ca967f7878909596969277777b9d9d9d9d8d779dd7837777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9d4a9 d4a9d481d481d481d42323e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9a9a9a981a9 d4a9d4a9d4a9d45743e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c3d4d4 75233a75171717173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0aae0e0e003e003e083e0aae075e075e03ae0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffff6d6d6d6dffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0f7e0f7e0f7e0f7e0f7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07575aaaaaa757575757575757575753a3a75e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07878787878c0dbdd897879d5dcdbdcc978788ddcd4d4dba97779d0a17777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e081a9a9a9 a9a981a981a981a9812323e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9a9a9818181 a981a9818181814357e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075c375 233ae075171717173a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e091e03ae023e03ae0e0e075e03ae0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffff6d6d6d75ffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0f7e0f7f7f7f7f7f7f7e0f7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075e0e0d4d4e0d4aaaa757575aaaa753a3a7575e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe078787878787a97da7d7880dc917ab9bb787899d67b7ad69b7777c1af7777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0437e7e 7e7e7e7e7e7e7e7e7e2325e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9d47e7e7e7e7e 7e7e7e7e7e7e252557e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e03a3a 3ae0e075171717233a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e091e03ae023e0aae075e03ae0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffa8d3ff6d6d6d75ffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0f7f7f7f7f7f7f7e0d7d7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075d4d4d4d4d4e0e0e0e0d4aa75753a3a753a75e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878a3d178788ddc8278c6ac7878a8ca7882db8d7777caa57777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0437e 437e437e43434343432325e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a9a9437e437e43 4343434343252557e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e075171717233a3ae083e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e003e091e03ae003e0e0e03ae03ae0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffa8f76d6d6d6d3ad3ff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0f7f7f7f7d7f7f7f7d7d7e0f7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075d4aad4d4d4d4d4d4d4d4d4d4d43a3a3a75753a 9be0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878b0c378789bd77978d39f7878b6bb788fdb80777ad5977777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e043 7e437e4343434343432557e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e081d47e437e4343 43434343252557e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4d4d4d4d4d4 d4d4d4aaaa1723233a3ae08383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0aae0e0e03ae03ae03ae0aae07de03ae003e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffd3d3d76d6d6d6d2277a8 ffffffffffffffffffff0000ff00ffff00ffffffffffffffffffffffffffffffffff00ff ffffff00ffffffff00ff00ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff00ff00ffffffffffff00ffffffffffffffffffffffffffffff00ff ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0f7c0c0c0c0d7d7d7f7d7e0f7e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075d4aaaaaaaaaaaaaaaaaaaaaaaa3a3a3a753a33 3a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878beb57878a8ca787edb917878c3ae789cd3797782db8a7777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 437e437e43434343432583e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e08181437e437e43 434343252557e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4aaaaaaaaaa aaaaaaaa752317233a3a838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e03ae075e0aae003e003e0aae0e0e07de003e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffa8f7d36d6d6d7577d7d3 75ffffffffffffffff00ffffffffffff00ffffffffffffffffffffffffffffffff00ffff ffff00ffffffff00ffff00ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff00ffff00ffffffffffff00ffffffffffffffffffffffffffffff00ff ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0a875757575a8d7d7d7f7f7e0f7e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e075d4aaaacdaacdaacdaacdaaaaaa3a3a753a3a33 3a9be0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787878cca77878b7bd788bdd837879d1a078aac8787790d97d7777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0437e43434323232323e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0000000 00000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e043252525257e43 434325255783838383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e000000000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4aaaaaaaaaa aaaaaaaa752323233a3a7575e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e03ae0e0e023e023e003e0aae075e003e03ae0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffa8f7d76d6d6d6d3af7d775 ffffffffffffffffff00ffffffffffff00ffffffffffffffffffffffffffffffff00ffff ffff00ffffffff00ffff00ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff00ffff00ffffffffffff00ffffffffffffffffffffffffffffff00ff ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e075a8d3757522a8d7f7f7f7f7e0e0e0e00000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07575aacdaacdaacdaacdaa9bcdaa3a3a3a3a333a 9be0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000000000e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe078787878787bd7997878c5ae7898d77b787dda9278b8b978779ed1787777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e083 8383437e43432525255783838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000 000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0437e43 43253a5783838383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e00000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0d4aa75aa75aa 75aa75aa7575233a753a7583e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e003e03ae023e003e0e0e083e03ae0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffd3f7d7d36d6d6d6d75d7d322 ffffffffffffffff00000000ff00ffff00ffffff000000ffffffff00ffffffff00ffffff ff00ffffffff00ffffff00000000ffffffff000000ffffff0000000000000000ffffffff 000000ffffffff00ffffff00ffff0000ffff00ffffff000000ffffffff000000ffff00ff ff0000ffffff000000ffffffff00ffffff00ffffff00ffffff000000ffffff00ffffffff ffe0ffe0ffe0e0e000000000000000e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 75a8d3a875753a22c0d7f7d7e0f7e0e0e00000e0e0e0e0e0e0e000000000e0e0e0e00000 0000e0e0e00000e00000e0e000000000e0e00000000000e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09b9b757575757575757575aaaa3a3a3a333a9b e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000000000e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0787878787882dd8b7879d2a078a6cd787889db8578c5ac7877abc4777777 7777e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 838383257e43252583838383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000 0000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0838383437e43 253a578383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0aa75757575 75757575757575753a758383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e03ae023e023e0aae075e03ae083e083e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffa8f7d7d36d6d6d7577d77575 ffffffffffffffffff00ffffff00ffff00ffff00ffffff00ffffff00ffffffff00ffffff ff00ffffffff00ffffff00ffffff00ffff00ffffff00ffff00ffffff00ffffff00ffff00 ffffff00ffffff00ffffff00ffff00ffffff00ffffffffffff00ffff00ffffff00ff00ff ff00ffffff00ffffff00ffffff00ffffffff00ff00ffffffffffffff00ffff00ffffffff ffe0ffe0ffe0e0e0e00000000000e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e03a3ae0 227575753a3a753ac0f7d7f7f7e0e0e0e00000000000e0e0e00000e0e00000e0e0e0e0e0 e00000e0e00000000000e00000e0e0e0e0e00000e0e00000e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09b9b75753a3a3a3a3a33333a9be0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0000000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797992dc80797edc9479b6bf797897d97b78d39f7878bab7787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e08383257e2525838383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 00e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e08383434325 3a57838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0aa75753a 3a3a3a3a173a3a3a758383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e075e0aae023e023e0aae0aae023e07de083e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffa8f7d7d36d6d226d75d3d722ff ffffffffffffffffff00ffffff00ffff00ffff0000000000ffffffffffffffff00ffffff ff00ffffffff00ffffff00ffffff00ffff00ffffff00ffff00ffffff00ffffff00ffff00 00000000ffffff00ffffff00ff00ffffffff00ffffff00000000ffff00ffffffffff00ff 00ffffffff0000000000ffffff00ffffffff00ff00ffffffff00000000ffff00ff00ffff ffe0ffe0ffe0e0e0e0e0000000e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e022c07575 d3c03a3a3a3a753ac0d7d7e0f7e0e0e0e0e00000000000e0e0000000000000e0e0e00000 000000e0e00000e0e0e0e00000e0e0e0e0e00000e0e00000e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09b3a333ae0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe079797979799fd47a798add8579c3b27978a5ce787fdb917878c8a9787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e08383252583838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e08383253a 57e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e083 83838383838383838383e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e03ae075e075e075e075e083e083e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffa8d3d7d3f76d22d76d75d7757777 ffffffffffffffffff00ffffff00ffff00ffff00ffffffffffffffffffffff00ffffffff 00ffffffff00ffffffff00ffffff00ffff00ffffff00ffff00ffffff00ffffff00ffff00 ffffffffffff00ffffffff000000ffffffff00ffff00ffffff00ffff00ffffffffff0000 00ffffffff00ffffffffffff00ffffffffff00ff00ffffff00ffffff00ffff00ff00ffff ffe0ffe0ffe0e0e0e0e0e000e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e07575a8d3 d3a83a223a223a75c0f7e0f7e0f7e0e0e0e0e0e0e00000e0e00000e0e0e0e0e0e00000e0 e00000e0e00000e0e0e0e00000e0e0e0e0e00000e0e00000e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07979797979adc8797998da7c79d0a37978b3c0788bdd83787ad49c787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffff77a8d36d22d7d76d22d3227575 7777ffffffffffffff00ffffff00ffff00ffff00ffffff00ffffff00ffffff00ffffffff 00ffffffff00ffffffff00ffffff00ffff00ffffff00ffff00ffffff00ffffff00ffff00 ffffff00ffff00ffffffff00ffff00ffffff00ffff00ffffff00ffff00ffffff00ff00ff ff00ffffff00ffffff00ffff00ffffffffffff00ffffffff00ffffff00ffffff00ffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e075a8d3d3a8 75753a22223a7580f7e0f7e0f7e0e0e0e000e0e0e00000e0e00000e0e0e000e0e00000e0 e00000e0e00000e0e0e0e00000e0e0e0e0e00000e0e00000e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07979797979bbb97979a6ce797ddb967978c0b27899d77b7880db8e787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffff22a8d3d3d7d3d7d322757575 7777ffffffffffffff00ffffff00ffff00ffffff000000ffffffff00ffff00ffffffff00 ffffffff00ffffffffff00ffffff00ffffff000000ffffff00ffffff00ffffff00ffffff 000000ffff00ffffffffff00ffffff00ffff00ffffff00000000ffffff000000ffff00ff ffff00ffffff000000ffff00ffffffffffffff00ffffffffff00000000ffffff00ffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e07575d3d3a87575 753a2275808080e0e0a880a880a8e0e0e0e000000000e0e0e0e000000000e0e0e0e00000 000000e0e00000e0e0e0e0e000000000e0e00000e0e00000e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07979797979caab7979b4c17988de877979cea378a7cc78788edb81787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 00e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffff7722a8a8d7d3a822757777 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff00 ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffff00ffffffffffffff00ffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e075a8d3a87575753a 2275e0e0e0e0e0a8758080808080e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797ad59e7979c1b37995da7d797cda9778b5be78789ad579787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000000000e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0 00e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0babababae0e0e0bae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffff7722a8a8227777ffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e03a3a7575753a2275 e0e0e0e0a87575757575758080a8e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe07979797981dd907979cfa579a4d1797986dc8978c2b07878a9c978787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0 00e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0bae0e0e0e0bae0e0bae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffff77227777ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0753a3a753a758080 e0a8807575758080a8e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979798edd83797cda9779b2c2797994db7d78d0a27878b7ba78787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0 e0e0000000e0e0e0e0000000e0e000e0e00000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0000000e0e0e000e00000e000 e0e000e0e000e0e0e0000000e0e0e000e00000e0e000000000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e0e0000000e0e0e0 00e0e0e0000000e0e0e0e0000000e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0bae0e0e0e0e0e0babababae0e0bababae0e0e0babababae0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0a8223a2280808080 808080a8e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979799cd87b7988de8979c0b67979a2d1797edb957979c7ae78787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e00000000000e0e0 e0e0e0e0e000e0e000e0e0e000e000e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e000e0e0e000e0e00000e0e0e000 e0e000e0e000e0e0e0e0e0e000e0e00000e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e000e0e0e000e0e0 00e0e000e0e0e000e0e0e0e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0babae0e0e0e0e0bae0e0e0bae0e0e0bae0e0bae0e0e0bae0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffe0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e000e00000e000e0e000000000e0e0 00000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe079797979abcc797994db7d79cda77979b0c57988de87797ad3a078787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0 e0e000000000e0e000e0e0e0e0e000e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e000e0e0e000e0e000e0e0e0e000 e000e000e000e0e0e000000000e0e000e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0e0e00000000000e0e0 00e0e000e0e0e000e0e0e000000000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0babae0e0e0bae0e0e0bae0e0e0bae0e0bae0e0e0bae0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09c00e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0ffe0ffe0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0ffe0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e00000e0e0e000e0e000e0e0e000e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe079797979b8d9c8c8d0d37a7cd9d0c8c8d6b77996dec9c7c8dd9378787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0 e000e0e0e000e0e000e0e0e0e0e0000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e000e0e0e000e0e000e0e0e0e000 e000e000e000e0e000e0e0e000e0e000e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e000e0e0e0e000e0e0e0e0e0e0 00e0e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0bae0e0bae0e0e0bae0e0e0bae0e0bae0e0e0bae0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffe09c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9ce0e0e0e0e0ff9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9ce0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0e000e0e0e0e000e0e000e0e0e000e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979799faeaeaeaea1797daeaeaeaeae93798eaeaeaeaead8078787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e000e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e000e0e0e000e0e000e0e0e0e0e0 00e0e0e000e0e0e000e0e0e000e0e000e0e0e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e000e0e0e000e0e0 00e0e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0bae0e0e0e0bae0e0bae0e0e0bae0e0e0bae0e0bae0e0e0bae0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e000e0e0e0e000e0e000e0e0e000e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797979797979797979797979797979797979797979787878787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e00000000000e0e0 e0e000000000e0e0e0000000e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0000000e0e0e000e0e0e0e0e0 00e0e0e000e0e0e0e000000000e0e000e0e0e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0e0e0000000e0e0e0 00e0e0e0000000e0e0e0e000000000e0e0e000000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0babababae0e0e0e0babae0e0bababae0e0e0babababae0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e000e0e0e0e000e0e000e0e0e000e0 e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797979797979797979797979797979797979797979787878787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0bae0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e000e0e0e0e000e0e000e0e0e000e0 e0e00000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797979797979797979797979797979797979797979787878787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0bae0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0797979797979797979797979797979797979797979797979787878787878 7878e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e09c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0ffe0e0e03ae0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e000ff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c00e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0000000000000000000000000000000000000000000000000000000000000000000 0000000000e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e09cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e09cffffe9e9e97400 00ffe9e9e9749cff9c9c9c9c9c9c9c9c9cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9cffffe9e9e97400 00ffe9e9e9749cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffff9cffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffff9ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0 ffe0e0e0e0e0ffe0e0e09cffe0e0e0e0e0e0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0ffe0 e0e0e0e0ffe0e0e0e0e0ffe0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e03ae0e0e0e0ffe0e0e03ae0ffe0e0e03ae0ffe0e0e03ae0ffe0e0 e03ae0ffe0e0e03ae0e09cffe0e03ae0e0e0e0ffe0e0e03ae0ffe0e0e03ae0ffe0e0e03a e0ffe0e0e03ae0ffe0e0e03ae0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e03a3ae0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0 e0e0e0e03ae0e0e0e0e09cffe0e03a3ae0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0e0e0 e0e03ae0e0e0e0e03ae0e0e0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e03a753ae0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0 ffe0e0e0e0e0ffe0e0e09cffe0e03a753ae0e0e0e0e0ffe0e0e0e0e0ffe0e0e0e0e0ffe0 e0e0e0e0ffe0e0e0e0e0ffe0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e03a75ffe0e0ffe0e0e03ae0ffe0e0e03ae0ffe0e0e03ae0ffe0e0 e03ae0ffe0e0e03ae0e09cffe0e03a75ffe0e0ffe0e0e03ae0ffe0e0e03ae0ffe0e0e03a e0ffe0e0e03ae0ffe0e0e03ae0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e03affe0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0 e0e0e0e03ae0e0e0e0e09cffe0e03affe0e0e0e03ae0e0e0e0e03ae0e0e0e0e03ae0e0e0 e0e03ae0e0e0e0e03ae0e0e0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e09ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0ffffe9e9e97400 00ffe9e9e9749cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9cffffe9e9e97400 00ffe9e9e974000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000ffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffff0000ffffffffffffffffffffff ffffffffffffffff000000000000ff00ffffffff000000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffff ffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffff000000ffffffffffffffffffff ffffffffffffff000000ffffff000000ffffffff000000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffff ffffffffffffffffffffffffffffff0000ffff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffff00000000ffffffffffffffffffff ffffffffffff000000ffffffffff0000ffffffff000000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffff ffffffffffffffffffffffffffff000000ffff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffff0000000000ffffffffffffffffff ffffffffffff000000ffffffffffff00ffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffff ffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffff00ff000000ffffffffffffffffff ffffffffffff000000ffffffffffff00ffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffff ffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffff0000ff000000ffffffffffffffffff ffffffffffff00000000ffffffffffffffffff00000000ffffff00000000ffff00000000 ffffff00000000ffffffff00000000ffff000000ffffffffffff000000ffffffffffff00 00000000ffffffffffffffffff000000000000ffffffffff0000000000ffffffffff0000 0000ff00000000ffff00000000ffff00000000ffffff00000000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffff0000ffff000000ffffffffffffffff ffffffffffff000000000000ffffffffffffffff000000ffffffff000000ff0000000000 ff00000000000000ffffffff000000ff000000000000ffffffff000000ffffffff000000 ffff000000ffffffffffffffffff000000ffffffffff00000000ff00000000ffffffff00 000000ffff000000ffff000000ff0000000000ff00000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffff00ffffff000000ffffffffffffffff ffffffffffffff00000000000000ffffffffffff000000ffffffff00000000ffffff0000 0000ffffff000000ffffffff0000000000ffff000000ffffffff000000ffffffff0000ff ffff000000ffffffffffffffffff000000ffffffffff000000ffffff000000ffffffff00 0000ffff00000000ffff00000000ffffff00000000ffffff000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffff0000ffffff000000ffffffffffffffff ffffffffffffffffff00000000000000ffffffff000000ffffffff000000ffffffff0000 00ffffffff000000ffffffff00000000ffffffff000000ffffff000000ffffff000000ff ffffff000000ffffffffffffffff000000ffffffff000000ffffffffff000000ffffff00 0000ffffff0000ffffff000000ffffffff000000ffffffff000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffff00ffffffffff000000ffffffffffffff ffffffffffffffffffff000000000000ffffffff000000ffffffff000000ffffffff0000 00ffffffff000000ffffffff000000ffffffffff000000ffffff000000ffffff000000ff ffffff000000ffffffffffffffff000000ffffffff000000ffffffffff000000ffffff00 0000ffffffffffffffff000000ffffffff000000ffffffff000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffff00ffffffffff000000ffffffffffffff ffffffffffffffffffffffff0000000000ffffff000000ffffffff000000ffffffff0000 00ffffffff000000ffffffff000000ffffffffff000000ffffff000000ffffff00000000 000000000000ffffffffffffffff000000ffffffff000000ffffffffff000000ffffff00 0000ffffffffffffffff000000ffffffff000000ffffffff000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffff00000000000000000000ffffffffffffff ffffffffffff00ffffffffffff00000000ffffff000000ffffffff000000ffffffff0000 00ffffffff000000ffffffff000000ffffffffff000000ffffff000000ffffff000000ff ffffffffffffffffffffffffffff000000ffffffff000000ffffffffff000000ffffff00 0000ffffffffffffffff000000ffffffff000000ffffffff000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffff00ffffffffffff00000000ffffffffffff ffffffffffff00ffffffffffffff000000ffffff000000ffffffff000000ffffffff0000 00ffffffff000000ffffffff000000ffffffffff000000ffffff000000ffffff000000ff ffffffffffffffffffffffffffff000000ffffffff000000ffffffffff000000ffffff00 0000ffffffffffffffff000000ffffffff000000ffffffff000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffff0000ffffffffffffff000000ffffffffffff ffffffffffff0000ffffffffffff000000ffffff000000ffffffff000000ffffffff0000 00ffffffff000000ffffffff000000ffffffffff000000ffffff000000ffffff00000000 ffffffffffffffffffffffffffff000000ffffffff000000ffffffffff000000ffffff00 0000ffffffffffffffff000000ffffffff000000ffffffff000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffff0000ffffffffffffff00000000ffffffffff ffffffffffff000000ffffffffff0000ffffffff000000ffffffff000000ffffffff0000 00ffffffff000000ffffffff00000000ffffff000000ffffffff000000ffffffff000000 00ffffff00ffffffffffffffffff000000ffffffffff000000ffffff000000ffffffff00 0000ffffffffffffffff000000ffffffff000000ffffffff000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffff000000ffffffffffffff00000000ffffffffff ffffffffffff00000000ffffff000000ffffffff000000ffffffff000000ffffffff0000 00ffffffff000000ffffffff000000ff000000000000ffffffff000000ffffffff000000 00000000ffffffffffffffffffff000000ffffffffff00000000ff00000000ffffffff00 0000ffffffffffffffff000000ffffffff000000ffffffff000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffff0000000000ffffffff0000000000000000ffffff ffffffffffff00ff00000000000000ffffffff0000000000ffff0000000000ffff000000 0000ffff0000000000ffffff000000ffff000000ffffffffff0000000000ffffffffff00 000000ffffffffffffffffffff0000000000ffffffffffff0000000000ffffffffff0000 00000000ffffffffff0000000000ffff0000000000ffff0000000000ffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffffff5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffffff5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f57cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7cfffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7cf5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffff00ffffffffffffffffffffffffffff ffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffff00ffffffffffffffffffffff00ffffffffffffff00ff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff ffffffffffffffff00ffff00ffff00ffffffffffffffffffff0000ffffffffffff0000ff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0 e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0 e0e0e0000000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffff00ff00ffffffffffffffffffffffffff ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff ffffffffffffffff00ffffffffffffffffffffffffffffffffff00ffffffffffffff00ff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0 e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0 e0e000e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffff00ff0000ffffffffff00ff000000ffff ffffffffff00ffffffff00ff000000ffffff00ff000000ffff0000ffffff0000ff000000 00ffffffffffffff00ffffffffff00ffffffff000000ffffffff00ffffffff0000ff00ff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0 e000e0e0e000e0e000000000e0e0e00000000000000000e0e0e000e000000000e0e0e0e0 e000e0e0e0e0e000e0e000e0e0e000e0e0e0000000e0e0e000e00000e000e0e0e000e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffff00ffffff00ffffffff000000ffff0000ff ffffffffff00ffffff000000ffff0000ff000000ffff0000ffff00ffffffff00ffff00ff ffffffffffffff00000000ffff0000ffffff00ffffff00ffffff00ffffff00ffff0000ff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000e0e0e0e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e000e0e000e0e000e0e0e0e0e0e0 e000e0e0e0e0e000e0e000e0e0e000e0e000e0e0e000e0e00000e0e0e0e000e000e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffff00ffffff0000ffffffff00ffffffff00ff ffffffffff00ffffffff00ffffffff00ffff00ffffffff00ffff00ffffffff00ffff00ff ffffffffffffffff00ffffffffff00ffff00ffffffff00ffffff00ffff00ffffffff00ff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e00000e0e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e000e0e000e0e000e0e0e0e0e0e0 e000e0e0e0e0e000e0e000e0e0e000e0e00000000000e0e000e0e0e0e0e000e000e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffff00ffffffffff00ffffffff00ffffffff00ff ffffffffff00ffffffff00ffffffff00ffff00ffffffff00ffff00ffffffff00ffff00ff ffffffffffffffff00ffffffffff00ffff000000000000ffffff00ffff00ffffffff00ff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e000e0e000e0e000e0e0e0e0e0e0 e000e0e0e0e0e000e0e000e0e0e000e0e000e0e0e0e0e0e000e0e0e0e0e000e000e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffff00000000000000ffffffff00ffffffff00ff ffffffffff00ffffffff00ffffffff00ffff00ffffffff00ffff00ffffffff00ffff00ff ffffffffffffffff00ffffffffff00ffff00ffffffffffffffff00ffff00ffffffff00ff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e000e0e000e0e000e0e0e0e0e0e0 e0e000e0e0e000e0e0e000e0e0e000e0e000e0e0e000e0e000e0e0e0e0e0e000e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffff00ffffffffffff0000ffffff00ffffffff00ff ffffffffff00ffffffff00ffffffff00ffff00ffffffff00ffff00ffffffff00ffff00ff ffffffffffffffff00ffffffffff00ffff00ffffffffffffffff00ffff00ffffffff00ff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000000000e0e0 e0e000000000e0e000000000e0e0e000e0e0e000e0e0e000e0e000e0e0e00000e0e0e0e0 e0e0e0000000e0e0e0e0e000000000e0e0e0000000e0e0e000e0e0e0e0e0e000e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffff00ffffffffffffff00ffffff00ffffffff00ff ffffffffff00ffffffff00ffffffff00ffff0000ffffff00ffff00ffffff000000ff00ff 00ffffffffffffff00ffffffffff00ffffff00ffffff00ffffff00ffffff00ffff000000 ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffff000000ffffffffff00000000000000ffff000000 ffffffff000000ffff000000ffff000000ff00ff000000ffffffff000000ff00ffffff00 ffffffffffffff00000000ffff000000ffffff000000ffffff000000ffffff0000ff00ff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e00000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff7c7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffff5f5fffffffff5f5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e07c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff7c7cf5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5fffffffff5f57c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffff7cf5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5 f5f5f5f5f5fffffffff57c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c 7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7cffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749c00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9749ce0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0ffe9e9e97400 00ffe9e9e9749cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffff9cffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff9cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9cffffffff ffffffffffffffffffffffffffffffffffffffffffffff9cffffffffffffffffffffffff ffffffffff9cff9cffffe9e9e97400 0074747474749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cff747474747400 00ffffffff749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cffffffffff7400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0d73ae0e0e0d73a66e0e0d7a866e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0a8a8a8a8a87575757575577557e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e09999e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0757575e0666666e0464646e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e06f6f 6f3a3a3ae09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0d73ad7f7ffd7d366d7a83ae0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e066ffff57ff27ff57a8ff75ff75e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0d3ffd3d3e000ff996d00e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e03a3a3a3a3a3a66666666464646463a66e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e04242424242424242e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0753a3ae0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e06fc0c3 8ac0c06f3a9cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0d7f73aff3ad7f7a83a66e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e06627ffffffffffff27ff57ff57e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0d3ffffffffffd300ff996d0000e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f7f7f7f7f7f7f7f7f7f7f73a66e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e042e9ffffffffff5fe0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0000000 0000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e00000000000e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0000000e0 e0e0e0e0e0e0e0000000e0e0e00000000000e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e075ffd33a75753ae0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e06f6fc0 002c6fc33a9cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0d7f7a83ad73aa8d7f766e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e066ffff664cffffffa8ff27ff27e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0d3ffffffffd3ffd3d7cc996d000099e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f7f7f7f7f7753a75f7f7f73a66e0e0e0e0e0e0e0e0e0e0e0e0e0424242 42424297e86a42d4ffbf42e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e000e0e0e000 e0e0e0e0e0e000e0e0e000e0e0e0e0e0e000e0e0000000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e075a8d327d3ffd33ae0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e03ac06f e0e025c33a9cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0d7a83aa8d7a8663ad73a6666e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e06657ff4c4cffffff57ff75ff75e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e03ad3ffd3d7d3d7d3d7d399cc000099e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af775757575f7f7f73a3a3af7f7f73a66e0e0e0e0e0e0e0e0e0e0e0e04280e8ff e88042af5f4295ffe85642e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e0e000e0e0e0000000e0e0e0e0000000e0e000e0e0e000e0e00000000000000000e0e0 e0e0000000e0e0e000000000e0e000000000e0e000e0e0e0e0e0e0e000e0e0e0e0e000e0 e0e0000000e0e0e000000000e0e0e0e0000000e0e0e0e0e0e0e000e0e0e0e000e0e0e000 e0e0e0e0e0e000e0e0e000e0e0e0e0e000e0e0e0e0e000e0e0e0e0e0e0e0e0e0000000e0 e0e0000000e0e0e0e0000000e0e0e0000000e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e03a3aa8d327a8a8a83a3ae0e0e0e0e0e0e09cffe0e06f6f6f6f6f6f3ac06f 6fe06f00009cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e066d7f7f7f7f7f7f7f7f7d7f7d3f7d3d73ae0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e066ffffffffffffffa8ff57ff57e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0993ad3d7d3d7d3d7cc996d000099d3ffe0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f7f7f7f7f7753a75f7f7f73a66e0e0e0e0e0e0e0e0e0e0e0426affd442 d4ff42e0426affff6a42e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e0e000e0e000e0e0e000e0e000e0e0e000e000e0e0e000e0e000e0e0e000e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e0e000e0e0e0e0e0e0e000e0e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e000e0e0e0e000e0e0e000 e0e0e0e0e0e000e0e0e000e0e0e0e0e000e0e0e0e0e000e0e0e0e0e0e0e0e000e0e0e0e0 e000e0e0e000e0e000e0e0e000e000e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cff757575 757575757575d33aa8d327a8a8a83ad3003a3a3a3a3a3a9cffe06fc3006c6c6c6c6f6f6f 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0663a3ad7a83aa8d7a83a3ad73a3a3a66e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0666627ffff66f766ff27ff75ff75333333e0e0e0e0e0 e0e0e0e0e0e0e0e0e0993ad3d7d3d7cc996d0000d7d3d7d3ffe0e0e0e0e0e0e0e0e0e0e0 e0e0e03af775757575f7f73af7f7f73af7f73a66e0e0e0e0e0e0e0e0e0e0e042bfff8042 6ab4424256e8ff95424242e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e0e000e0e000e0e0e000e0e000e0e0e0e0e000e0e0e000e0e000e0e0e000e0e0e000e0 e00000000000e0e000e0e0e000e0e000e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e00000000000e0e0e0e0e0e000e0e0e0e000e0e0e000 e0e0e0e0e0e000e0e0e000e0e0e0e000e0e0e0e0e0e000e0e0e0e0e0e0e0e00000e0e0e0 e00000000000e0e000e0e0e0e0e00000e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffd3d3a8 d3a8a8a8a83aa83aa8d327a8a8a83aa83aa8a8a8a8a8a89cffe03ac38ac3c3c3c3c3c32c 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0d7d7a83ad73aa866d73a66ffa8a8a8a8 a8a8e0e0e0e0e0e0e0e0e0e0e021333affffffccf7ccffa8ff75ff75333333e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0993ad3d3cc996d0000d7d3d7d3d7d3ff00e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f7f7f73a3a3af73a3a3af73a66e0e0e0e0e0e0e0e0e0e0e042bfff8042 42564242bfffbf4242a980e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e0e000e0e000e0e0e000e0e000e0e0e0e0e000e0e0e000e0e000e0e0e000e0e0e000e0 e000e0e0e0e0e0e000e0e0e000e0e000e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e0e0e0e0e0e0e0e000e0e0e0e000e0e0e000 e0e0e0e0e0e000e0e0e000e0e0e0e000e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e00000e0 e000e0e0e0e0e0e000e0e0e0e0e0e0e00000e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cff3a3a3a 3a3a3a3a3a3a753aa8d327a8a8a83a753a3a3a3a3a3a3a9cffe03ac3c34b4b4b4b4b2c6f 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e066d7d73af73ad3d73a3a75a875757566 a8e0e0e0e0e0e0e0e0e0e0e0e0757575757575757575757575757533333333e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0993acc99000000d7d3d7d3d7d30000e0e0e0e0e0e0e0e0e0e0 e0e0e03af775757575f73a3a3a3a3a3a3af73a66e0e0e0e0e0e0e0e0e0e0e0426affe856 6aff8280ffe85656a9ff58e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e000e0e0 e0e000e0e0e000e0e0e000e0e000e0e0e000e000e0e0e000e0e000e0e0e000e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e0e000e0e0e0e0e0e0e000e0e0e0e000e0e0 e000e0e0e000e0e000e0e0e000e0e000e0e0e000e0e0e0e0e0e000e0e0e0e000e0e0e000 e0e0e000e0e000e0e0e000e0e0e000e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e000e0 e000e0e0e000e0e000e0e0e000e0e0e0e000e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e03a3aa8d3277575753a3ae0e0e0e0e0e0e09cffe03ac38a6c6c6c6c6c6c2c 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e066d7ccd7d3f7d3d73ad73a6675666666a8 e0e0e0e0e0e0e0e0e0e0e0e0e075757575757575757575753a753a33333a66e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0d7a2d70000d7d3d7d3d70000d3e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f7f7f73a3a3a3a3a3a3af73a66e0e0e0e0e0e0e0e0e0e0e0e04284e8ff e8c942e8ffffffffffe242e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0000000 0000e0e0e0e0e0000000e0e0e0e0000000e0e0e000000000e0e000e0e0e000e0e0e000e0 e0e0000000e0e0e000e0e0e000e0e0e00000e0e000e0e0e0e0e0e0e00000000000e0e0e0 e0e0000000e0e0e000e0e0e000e0e0e0000000e0e0e0e0e0e0e0e000e0e0e0e0000000e0 e0e0e000e0e0e0000000e0e0e0e000e0e0e0e0e00000000000e0e0e0e0e0e0000000e0e0 e0e0000000e0e0e0e0000000e0e0000000e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e03aa875277575753ae0e0e0e0e0e0e0e09cffe03ac3c34b4b4b4b4b2c6f 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0d7cc3a663ad73a3a3a75d73a666666a8a8 e0e0e0e0e0e0e0e0e0e0e0e0e075753a753a753a753a753a753a75333366e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0a2ffa2a299d3d7d30000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03af7f7f7f766f7f7f7f7f766f7f7f73a66e0e0e0e0e0e0e0e0e0e0e0e0e0424242 4242424242424242424242e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e00075753a3a3a3ae0e0e0e0e0e0e0e0e09cffe03ac38a6c6c6c6c6c6c6f 00e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e03a66a8a8d73a7566e0e03a66a8e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e044a244e03a3a0000d3e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e03a3a3a3a3ae03a3a3a3a3ae03a3a3a3ae0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e000e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e03a3a3ae0e0e0e0e0e0e0e0e0e0e0e09cffe06f3a2525252525250000 6fe0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e09cffe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0 e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e09cffe0e0e0e0e0e0e0e0e0e0e0 e0e0e0e0e09cff9cffffe9e9e97400 00ffe9e9e9749cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9cff9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9cff9c9c9c 9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9cff9c9c9c9c9c9c9c9c9c9c9c 9c9c9c9c9c9cff9cffffe9e9e97400 00ffe9e9e9749cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e974ffffffffffffffffffffffffffffffffffff74ffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff74ffffffffffffffffffff ffffffffffffffffffffe9e9e97400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 00ffe9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e974ffe9e9e9e9e9e9e9e9e9 e9e9e9e9e9e9e9e9e9e9e9e9e97400 007474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747474747474747474747474747474747474747474747474 747474747474747474747474747400 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000 showpage % stop using temporary dictionary end % restore original state origstate restore %%Trailer yaws-2.0.2/doc/README.rss0000664000175000017500000000575312605311412011661 00000000000000 RSS FEED INTERFACE ------------------ RSS is very cool! To see it in action look no further than Firebird 1.0. Then go to an RSS-enabled site, e.g slashdot.org . Note the little orange icon down in the right corner of the browser window. Click on the icon and add the RSS-feed to you personal toolbar. Then click on your toolbar, on the RSS-bookmark and watch the nice menu of slashdot article-summarys popping up. The module yaws_rss.erl provides an RSS store/interface so that you can RSS enable your application. More documentation can be found in the yaws_rss.erl file (edoc). TO CREATE AN RSS FEED -------------------- Make sure your top page has the corresponding link information in the 'head' part as shown in the example below: index.html ========== {content, "text/xml", ""} end. head() -> " Exampel RSS feed http://www.blaha.org/ Bla bla.... en". tail() -> " ". ======== To insert RSS items into the feed from your application, you can write code like: .... yaws_rss:insert(test, xml, "Yaws now support RSS feeds.", "http://www.blaha.org/latest_news.html", "Yaws has now been extended to support....", "Bill Smith"). .... First comes the application (RSSid) then a tag (these were used in rss.yaws when we retrieved the RSS content). Then follows the Title, Link, Description and Creator. The idea is that several independent application should be able to use the yaws_rss.erl API without affecting each other. Also, one application may have several RSS feeds (hence the Tag). HOW TO CONFIGURE RSS -------------------- Inside a block you specify the application you want to produce RSS content as: rss_id = rss_dir = The rss_id corresponds to the 'App' argument above and must be defined by the application in question. So, for example, the wiki application is using 'wiki' as rss_id. The rss_dir setting specifies the directory where the RSS database resides. Both are mandatory. Other, non-mandatory, configuration parameters are (with explanation and default values): rss_expire = false | days # expire items, or not (false) rss_days = # days until expired rss_rm_exp = # remove expired items (false) rss_max = # max no.of items stored (infinite) Good luck ! Tobbe yaws-2.0.2/doc/yaws.tex0000664000175000017500000047311712605311412011703 00000000000000\documentclass[11pt,oneside,english]{book} \usepackage{ifpdf} \ifpdf \usepackage[pdftex]{graphicx} \pdfcompresslevel=9 \DeclareGraphicsExtensions{.png,.jpg,.pdf,.mps} \else \usepackage{graphicx} \DeclareGraphicsExtensions{.ps,.eps} \fi \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} \usepackage{geometry} \geometry{verbose,letterpaper,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in} \usepackage{babel} \setcounter{secnumdepth}{3} \setlength\parskip{\medskipamount} \setlength\parindent{0pt} \usepackage{url} \usepackage{pslatex} \usepackage[colorlinks=false]{hyperref} \newcommand{\Erlang} % Write Erlang correctly {{\sc Erlang}} \newcommand{\Yaws} % Write Yaws correctly {{\sc Yaws}} \makeatletter \usepackage[T1]{fontenc} \usepackage{xspace} %\usepackage{html} \makeatother \begin{document} \title{Yaws - Yet Another Web Server} \author{Claes Wikstrom\\ klacke@hyber.org} \maketitle \tableofcontents{} \chapter{Introduction} \begin{figure}[h] \begin{center} \includegraphics[scale=0.6] {yaws_head} \end{center} \end{figure} \Yaws\ is an \Erlang\ web server. It's written in \Erlang\ and it uses \Erlang\ as its embedded language similar to PHP in Apache or Java in Tomcat. The advantages of \Erlang\ as an embedded web page language as opposed to Java or PHP are many. \begin{itemize} \item{Speed - Using \Erlang\ for both implementing the web server itself as well as embedded script language gives excellent dynamic page generation performance.} \item{Beauty - Well this is subjective} \item{Scalability - due to the lightweight processes of \Erlang{}, \Yaws\ is able to handle a very large number of concurrent connections} \end{itemize} \Yaws\ has a wide feature set; it supports: \begin{itemize} \item HTTP 1.0 and HTTP 1.1 \item Static content page delivery \item Dynamic content generation using embedded \Erlang\ code in the HTML pages \item NCSA combined/XLF/ELF log format traffic logs \item Virtual hosting with several servers on the same IP address \item Multiple servers on multiple IP addresses \item HTTP tracing for debugging \item An interactive interpreter environment in the Web server for use while developing and debugging a web site \item RAM caching of commonly accessed pages \item Full streaming capabilities of both upload and download of dynamically generated pages \item SSL \item Support for WWW-Authenticated pages \item Support API for cookie based sessions \item Application Modules where virtual directory hierarchies can be made \item Embedded mode \item WebSockets (RFC 6455) \item Long polling (COMET) applications \item Forward and reverse proxying \end{itemize} \section{Prerequisites} This document requires that the reader: \begin{itemize} \item Is well acquainted with the \Erlang\ programming language. \item Understands basic Web technologies. \end{itemize} \section{A tiny example} We introduce \Yaws\ by help of a tiny example. The web server \Yaws\ serves and delivers static content pages similar to any old web server, except that \Yaws\ does this much faster than most web servers. It's the dynamic pages that makes \Yaws\ interesting. Any page with the suffix ``.yaws'' is considered a dynamic \Yaws\ page. A \Yaws\ page can contain embedded \Erlang\ snippets that are executed while the page is being delivered to the WWW browser. Example 1.1 is the HTML code for a small \Yaws\ page. \begin{figure}[h] \begin{verbatim}

First paragraph out(Arg) -> {html, "

This string gets inserted into HTML document dynamically"}.

And here is some more HTML code \end{verbatim} \caption{Example 1.1} \end{figure} It illustrates the basic idea behind \Yaws{}. The HTML code, generally stored in a file ending with a ``.yaws'' suffix, can contain \verb++ and \verb++ tags and inside these tags an \Erlang\ function called \verb+out/1+ gets called and the output of that function is inserted into the HTML document, dynamically. It is possible to have several chunks of HTML code together with several chunks of \Erlang\ code in the same \Yaws\ page. The \verb+Arg+ argument supplied to the automatically invoked \verb+out/1+ function is an \Erlang\ record that contains various data which is interesting when generating dynamic pages. For example the HTTP headers which were sent from the WWW client, the actual TCP/IP socket leading to the WWW client. This will be elaborated on thoroughly in later chapters. The \verb+out/1+ function returned the tuple \verb+{html, String}+ and \verb+String+ gets inserted into the HTML output. There are number of different return values that can be returned from the \verb+out/1+ function in order to control the behavior and output from the \Yaws\ web server. \chapter{Compile, Install, Config and Run} This chapter is more of a ``Getting started'' guide than a full description of the \Yaws\ configuration. \Yaws\ is hosted on Github at \url{ https://github.com/klacke/yaws }. This is where the source code resides in a git repository and the latest unreleased version is available via git through the following commands: \begin{verbatim} $ git clone https://github.com/klacke/yaws \end{verbatim} Released version of \Yaws\ are available at \url{http://yaws.hyber.org/download}. \subsection{Compile and Install} To compile and install a \Yaws\ release one of the prerequisites is a properly installed \Erlang\ system. \Yaws\ runs on \Erlang\/OTP releases R14B02 and newer. Get \Erlang\ from \url{http://www.erlang.org/} Compile and install is straight forward: \begin{verbatim} # cd /usr/local/src # tar xfz yaws-X.XX.tar.gz # cd yaws # ./configure && make # make install \end{verbatim} The \verb+make+ command will compile the \Yaws\ web server with the \verb+erlc+ compiler found by the configure script. \begin{itemize} \item \verb+make install+ - will install the executable called \verb+yaws+ in \verb+/usr/local/bin/+ and a working configuration file in \verb+/usr/local/etc/yaws.conf+ \end{itemize} Alternatively, you can compile \Yaws\ with \verb+rebar+ as follows: \begin{verbatim} # rebar get-deps compile \end{verbatim} If you want to build with SOAP support, run the following command: \begin{verbatim} # YAWS_SOAP=1 rebar get-deps compile \end{verbatim} To create a \Yaws\ release with \verb+reltool+, execute the following command: \begin{verbatim} # rebar generate \end{verbatim} Because it bundles Erlang/OTP and all of the application's dependencies, the generated release found in \verb+rel/+ is standalone and has no external requirements. A future release of \verb+rebar+ will allow you to create a slim release that doesn't bundle Erlang/OTP. This is not yet available. While developing a \Yaws\ site, it's typically most convenient to do a \verb+local+ install and run \Yaws\ as a non-privileged user using \verb+--prefix+ option of the \verb+configure+ script: \begin{verbatim} # ./configure --prefix=/path/to/yaws && make install # /path/to/yaws/bin/yaws -i \end{verbatim} \subsection{Configure} Let's take a look at the config file that gets written after a \verb+local+ install in \verb+/home/klacke/yaws/+. The file is \verb+/home/klacke/yaws/etc/yaws/yaws.conf+: \begin{figure}[h] \begin{verbatim} # first we have a set of globals logdir = /home/klacke/yaws/var/log/yaws ebin_dir = /home/klacke/yaws/lib/yaws/examples/ebin include_dir = /home/klacke/yaws/lib/yaws/examples/include ... # and then a set of servers port = 8000 listen = 127.0.0.1 docroot = /home/klacke/yaws/var/yaws/www \end{verbatim} \caption{Minimal Local Configuration} \end{figure} The configuration consists of an initial set of global variables that are valid for all defined servers. The only global directive we need to care about for now is the logdir. \Yaws\ produces a number of log files. We start \Yaws\ interactively as \begin{verbatim} # ~/bin/yaws -i Erlang (BEAM) emulator version 5.1.2.b2 [source] Eshell V5.1.2.b2 (abort with ^G) 1> =INFO REPORT==== 30-Oct-2002::01:38:22 === Using config file /home/klacke/yaws/etc/yaws/yaws.conf =INFO REPORT==== 30-Oct-2002::01:38:22 === Listening to 127.0.0.1:8000 for servers ["localhost:8000"] 1> \end{verbatim} By starting \Yaws\ in interactive mode (using the command switch \textit{-i}) we get a regular \Erlang\ prompt. This is most convenient when developing \Yaws\ pages. For example we: \begin{itemize} \item{Can dynamically compile and load optional helper modules we need.} \item{Get all the crash and error reports written directly to the terminal.} \end{itemize} The configuration in Example 2.1 defined one HTTP server on address 127.0.0.1:8000 called "localhost". It is important to understand the difference between the name and the address of a server. The name is the expected value in the client HTTP \verb+Host:+ header. That is typically the same as the fully-qualified DNS name of the server whereas the address is the actual IP address of the server. Since \Yaws\ supports virtual hosting with several servers on the same IP address, this matters. Nevertheless, our server listens to \textit{127.0.0.1:8000} and has the name "localhost", thus the correct URL for this server is \verb+http://localhost:8000+. The document root (docroot) for the server is a copy of the \verb+www+ directory in the \Yaws\ source code distribution. This directory contains a bunch of examples and we should be able to run all those example now on the URL \verb+http://localhost:8000+. Instead of editing and adding files in the \Yaws\ \verb+www+ directory, we create yet another server on the same IP address but a different port number --- and in particular a different document root where we can add our own files. \begin{verbatim} # mkdir ~/test # mkdir ~/test/logs \end{verbatim} Now change the config so it looks like this: \begin{verbatim} logdir = /home/klacke/test/logs ebin_dir = /home/klacke/test include_dir = /home/klacke/test port = 8000 listen = 127.0.0.1 docroot = /home/klacke/yaws/var/yaws/www port = 8001 listen = 127.0.0.1 docroot = /home/klacke/test \end{verbatim} We define two servers, one being the original default and a new pointing to a document root in our home directory. We can now start to add static content in the form of HTML pages, dynamic content in the form of \verb+.yaws+ pages or \Erlang\ \verb+.beam+ code that can be used to generate the dynamic content. The load path will be set so that beam code in the directory \char`\~\verb+/test+ will be automatically loaded when referenced. It is best to run \Yaws\ interactively while developing the site. In order to start the \Yaws\ as a daemon, we give the flags: \begin{verbatim} # yaws -D --heart \end{verbatim} The \textit{-D} or \textit{--daemon} flags instructs \Yaws\ to run as a daemon and the \textit{--heart} flag will start a heartbeat program called heart which restarts the daemon if it should crash or if it stops responding to a regular heartbeat. By default, heart will restart the daemon unless it has already restarted 5 times in 60 seconds or less, in which case it considers the situation fatal and refuses to restart the daemon again. The \textit{-heart-restart=C,T} flag changes the default 5 restarts in 60 seconds to \textit{C} restarts in \textit{T} seconds. For infinite restarts, set both \textit{C} and \textit{T} to 0. This flag also enables the \textit{--heart} flag. Once started in daemon mode, we have very limited ways of interacting with the daemon. It is possible to query the daemon using: \begin{verbatim} # yaws -S \end{verbatim} This command produces a simple printout of uptime and number of hits for each configured server. If we change the configuration, we can HUP the daemon using the command: \begin{verbatim} # yaws -h \end{verbatim} This will force the daemon to reread the configuration file. \chapter{Static content} \Yaws\ acts very much like any regular web server while delivering static pages. By default \Yaws\ will cache static content in RAM. The caching behavior is controlled by a number of global configuration directives. Since the RAM caching occupies memory, it may be interesting to tweak the default values for the caching directives or even to turn it off completely. The following configuration directives control the caching behavior \begin{itemize} \item \textit{max\_num\_cached\_files = Integer} \Yaws\ will cache small files such as commonly accessed GIF images in RAM. This directive sets a maximum number on the number of cached files. The default value is 400. \item\textit{max\_num\_cached\_bytes = Integer} This directive controls the total amount of RAM which can maximally be used for cached RAM files. The default value is 1000000, 1 megabyte. \item\textit{max\_size\_cached\_file = Integer} This directive sets a maximum size on the files that are RAM cached by \Yaws{}. The default value is 8000 bytes, 8 batters. \end{itemize} It may be considered to be confusing, but the numbers specified in the above mentioned cache directives are local to each server. Thus if we have specified \verb+max_num_cached_bytes = 1000000+ and have defined 3 servers, we may actually use $3 * 1000000$ bytes. \chapter{Dynamic content} Dynamic content is what \Yaws\ is all about. Most web servers are designed with HTTP and static content in mind whereas \Yaws\ is designed for dynamic pages from the start. Most large sites on the Web today make heavy use of dynamic pages. \section{Introduction} When the client \verb+GET+s a page that has a ``.yaws'' suffix, the \Yaws\ server will read that page from the hard disk and divide it in parts that consist of HTML code and \Erlang\ code. Each chunk of \Erlang\ code will be compiled into a module. The chunk of \Erlang\ code must contain a function \verb+out/1+. If it doesn't the \Yaws\ server will insert a proper error message into the generated HTML output. When the \Yaws\ server ships a \verb+.yaws+ page it will process it chunk by chunk through the \verb+.yaws+ file. If it is HTML code, the server will ship that as is, whereas if it is \Erlang\ code, the \Yaws\ server will invoke the \verb+out/1+ function in that code and insert the output of that \verb+out/1+ function into the stream of HTML that is being shipped to the client. \Yaws\ will (of course) cache the result of the compilation and the next time a client requests the same \verb+.yaws+ page \Yaws\ will be able to invoke the already-compiled modules directly. \section{EHTML} There are two ways to make the \verb+out/1+ function generate HTML output. The first and most easy to understand is by returning a tuple \verb+{html, String}+ where \verb+String+ then is regular HTML data (possibly as a deep list of strings and/or binaries) which will simply be inserted into the output stream. An example: \begin{verbatim}

Example 1

out(A) -> Headers = A#arg.headers, {html, io_lib:format("You say that you're running ~p", [Headers#headers.user_agent])}. \end{verbatim} The second way to generate output is by returning a tuple \verb+{ehtml, EHTML}+ or \verb+{exhtml, EHTML}+. The exhtml variant generates strict XHTML code. The term \verb+EHTML+ must adhere to the following structure: $EHTML = [EHTML] | \{TAG, Attrs, Body\} | \{TAG, Attrs\} | \{TAG\} |\\* \hspace*{0.75 in} \{Module, Fun, [Args]\} | fun/0 |\\* \hspace*{0.75 in} binary() | character()$ $TAG = atom()$ $Attrs = [\{HtmlAttribute, Value\}]$ $HtmlAttribute = atom()$ $Value = string() | binary() | atom() | integer() | float() |\\* \hspace*{0.55 in} \{Module, Fun, [Args]\} | fun/0$ $Body = EHTML$ We give an example to show what we mean. The tuple \begin{verbatim} {ehtml, {table, [{bgcolor, grey}], [ {tr, [], [ {td, [], "1"}, {td, [], "2"}, {td, [], "3"} ] }, {tr, [], [{td, [{colspan, "3"}], "444"}]}]}}. \end{verbatim} expands into the following HTML code: \begin{verbatim} 2
1 3
444
\end{verbatim} At a first glance it may appears as if the HTML code is more beautiful than the \Erlang\ tuple. That may very well be the case from a purely aesthetic point of view. However the \Erlang\ code has the advantage of being perfectly indented by editors that have syntax support for \Erlang\ (read Emacs). Furthermore, the \Erlang\ code is easier to manipulate from an \Erlang\ program. Note that ehtml supports function calls as values. Functions can return any legal ehtml value, including other function values. \Yaws\ supports \verb+{M,F,[Args]}+ and \verb+fun/0+ function value forms. As an example of some more interesting ehtml we could have an \verb+out/1+ function that prints some of the HTTP headers. In the \verb+www+ directory of the \Yaws\ source code distribution we have a file called \verb+arg.yaws+. The file demonstrates the \verb+Arg+ \verb+#arg+ record parameter which is passed to the \verb+out/1+ function. But before we discuss that code, we describe the \verb+Arg+ record in detail. Here is the \verb+yaws_api.hrl+ file which is in included by default in all \Yaws\ files. The \verb+#arg{}+ record contains many fields that are useful when processing HTTP request dynamically. We have access to basically all the information associated with the client request such as: \begin{itemize} \item The actual socket leading back to the HTTP client \item All the HTTP headers -- parsed into a \verb+#headers+ record \item The HTTP request -- parsed into a \verb+#http_request+ record \item \verb+clidata+ -- data which is \verb+POST+ed by the client \item \verb+querydata+ -- this is the remainder of the URL following the first occurrence of a '?' character, if any. \item \verb+docroot+ -- the absolute path to the docroot of the virtual server that is processing the request. \end{itemize} \begin{verbatim} -record(arg, { clisock, % the socket leading to the peer client client_ip_port, % {ClientIp, ClientPort} tuple headers, % headers req, % request orig_req, % original request clidata, % The client data (as a binary in POST requests) server_path, % The normalized server path % (pre-querystring part of URI) querydata, % For URIs of the form ...?querydata % equiv of cgi QUERY_STRING appmoddata, % (deprecated - use pathinfo instead) the remainder % of the path leading up to the query docroot, % Physical base location of data for this request docroot_mount, % virtual directory e.g /myapp/ that the docroot % refers to. fullpath, % full deep path to yaws file cont, % Continuation for chunked multipart uploads state, % State for use by users of the out/1 callback pid, % pid of the yaws worker process opaque, % useful to pass static data appmod_prepath, % (deprecated - use prepath instead) path in front % of: prepath, % Path prior to 'dynamic' segment of URI. % ie http://some.host///d/e % where is an appmod mount point, % or .yaws,.php,.cgi,.fcgi etc script file. pathinfo % Set to '/d/e' when calling c.yaws for the request % http://some.host/a/b/c.yaws/d/e % equiv of cgi PATH_INFO }). -record(http_request, {method, path, version}). -record(headers, { connection, accept, host, if_modified_since, if_match, if_none_match, if_range, if_unmodified_since, range, referer, user_agent, accept_ranges, cookie = [], keep_alive, location, content_length, content_type, content_encoding, authorization, transfer_encoding, x_forwarded_for, other = [] % misc other headers }). \end{verbatim} There are a number of \textit{advanced} fields in the \verb+#arg+ record such as \verb+appmod+ and \verb+opaque+ that will be discussed in later chapters. Now, we show some code which displays the content of the \verb+Arg+ \verb+#arg+ record. The code is available in \verb+yaws/www/arg.yaws+ and after a \verb+local_install+ a request to \url{http://localhost:8000/arg.yaws} will run the code. \begin{verbatim}

The Arg

This page displays the Arg #argument structure supplied to the out/1 function. out(A) -> Req = A#arg.req, H = yaws_api:reformat_header(A#arg.headers), {ehtml, [{h4,[], "The headers passed to us were:"}, {hr}, {ol, [],lists:map(fun(S) -> {li,[], {p,[],S}} end,H)}, {h4, [], "The request"}, {ul,[], [{li,[], f("method: ~s", [Req#http_request.method])}, {li,[], f("path: ~p", [Req#http_request.path])}, {li,[], f("version: ~p", [Req#http_request.version])}]}, {hr}, {h4, [], "Other items"}, {ul,[], [{li,[], f("clisock from: ~p", [inet:peername(A#arg.clisock)])}, {li,[], f("docroot: ~s", [A#arg.docroot])}, {li,[], f("fullpath: ~s", [A#arg.fullpath])}]}, {hr}, {h4, [], "Parsed query data"}, {pre,[], f("~p", [yaws_api:parse_query(A)])}, {hr}, {h4,[], "Parsed POST data "}, {pre,[], f("~p", [yaws_api:parse_post(A)])}]}. \end{verbatim} The code utilizes four functions from the \verb+yaws_api+ module. The \verb+yaws_api+ module is a general purpose www API module that contains various functions that are handy while developing \Yaws\ code. We will see many more of those functions during the examples in the following chapters. The functions used are: \begin{itemize} \item \verb+yaws_api:f/2+ --- alias for \verb+io_lib:format/2+. The \verb+f/2+ function is automatically \verb+-included+ in all \Yaws\ code. \item \verb+yaws_api:reformat_header/1+ --- This function takes the \#headers record and unparses it, that is reproduces regular text. \item \verb+yaws_api:parse_query/1+ --- The topic of the next section. \item \verb+yaws_api:parse_post/1+ --- Ditto. \end{itemize} \section{POSTs} \subsection{Queries} The user can supply data to the server in many ways. The most common is to give the data in the actual URL. If we invoke: \verb+GET http://localhost:8000/arg.yaws?kalle=duck&goofy=unknown+ we pass two parameters to the \verb+arg.yaws+ page. That data is URL-encoded by the browser and the server can retrieve the data by looking at the remainder of the URL following the '?' character. If we invoke the \verb+arg.yaws+ page with the above mentioned URL we get as the result of \verb+yaws_api:parse_query/1+: $kalle = duck$ $goofy = unknown$ In \Erlang\ terminology, the call \verb+yaws_api:parse_query(Arg)+ returns the list: \begin{verbatim} [{"kalle", "duck"}, {"goofy", "unknown"}] \end{verbatim} Both the key and the value are strings. Hence, a web page can contain URLs with a query and thus pass data to the web server. This scheme works with any kind of requests. It is the easiest way to pass data to the Web server since no form is required in the web page. \subsection{Forms} In order to \verb+POST+ data a form is required. Say that we have a page called \verb+form.yaws+ that contain the following code: \begin{verbatim}

A Input field
\end{verbatim} This will produce a page with a simple input field and a submit button. \begin{figure}[h] \begin{center} \includegraphics[scale=0.6] {a} \end{center} \end{figure} If we enter something---say, ``Hello there''---in the input field and click the submit button the client will request the page indicated in the ``action'' attribute, namely \verb+post_form.yaws+. If that \Yaws\ page has the following code: \begin{verbatim} out(A) -> L = yaws_api:parse_post(A), {html, f("~p", [L])} \end{verbatim} The user will see the output \begin{verbatim} [{"xyz", "Hello there"}] \end{verbatim} The differences between using the query part of the URL and a form are the following: \begin{itemize} \item Using the query arg works with any kind of requests. We parse the query argument with the function \verb+yaws_api:parse_query(Arg)+ \item If we use a form and \verb+POST+ the user data the client will transmit the user data in the body of the request. That is, the client sends a request to get the page using the \verb+POST+ method and it then attaches the user data---encoded---into the body of the request. A \verb+POST+ request can have a query part in its URL as well as user data in the body. \end{itemize} \section{POSTing files} It is possible to upload files from the client to the server by means of \verb+POST+. We indicate this in the form by telling the browser that we want a different encoding. Here is an example form that does this: \begin{verbatim} out(A) -> Form = {form, [{enctype, "multipart/form-data"}, {method, post}, {action, "file_upload_form.yaws"}], [{input, [{type, submit}, {value, "Upload"}]}, {input, [{type,file}, {width, "50"}, {name, foo}]}]}, {ehtml, {html,[], [{h2,[], "A simple file upload page"}, Form]}}. \end{verbatim} As shown in the figure, the page delivers the entire HTML page with enclosing \verb+html+ markers. \begin{figure}[h] \begin{center} \includegraphics[scale=0.6] {b} \end{center} \end{figure} The user gets an option to browse the local host for a file or the user can explicitly fill in the file name in the input field. The file browsing part is automatically taken care of by the browser. The action field in the form states that the client shall POST to a page called \verb+file_upload_form.yaws+. This page will get the contents of the file in the body of the \verb+POST+ message. To read it, we use the \verb+yaws_multipart+ module, which provides the following capabilities: \begin{enumerate} \item It reads all parameters --- files uploaded and other simple parameters. \item It takes a few options to help file uploads. Specifically: \begin{enumerate} \item \verb+{max_file_size, MaxBytes}+: if the file size in bytes exceeds \verb+MaxBytes+, return an error \item \verb+no_temp_file+: read the uploaded file into memory without any temp files \item \verb+{temp_file,FullFilePath}+: specify \verb+FullFilePath+ for the temp file; if not given, a unique file name is generated \item \verb+{temp_dir, TempDir}+: specify \verb+TempDir+ as the directory to store the uploaded temp file; if this option is not provided, then by default an OS-specific temp directory such as \verb+/tmp+ is used \item \verb+list+: return file data in list form; this is the default \item \verb+binary+: return file data in binary form \end{enumerate} \end{enumerate} Note that the \verb+list+ and \verb+binary+ options affect only file data, not filenames, headers, or other parameters associated with each file. These are always returned as strings. Just call \verb+yaws_multipart:read_multipart_form+ from your \verb+out/1+ function and it'll return a tuple with the first element set to one of these three atoms: \begin{itemize} \item \verb+get_more+: more data needs to be read; return this tuple directly to \Yaws\ from your \verb+out/1+ function and it will call your \verb+out/1+ function again when it has read more \verb+POST+ data, at which point you must call \verb+read_multipart_form+ again \item \verb+done+: multipart form reading is complete; a \verb+dict+ full of parameters is returned \item \verb+error+: an error occurred \end{itemize} The \verb+dict+ returned with \verb+done+ allows you to query it for parameters by name. For file upload parameters, it returns one of the following lists: \begin{verbatim} [{filename, "name of the uploaded file as entered on the form"}, {value, Contents_of_the_file_all_in_memory} | _T] \end{verbatim} or: \begin{verbatim} [{filename, "name of the uploaded file as entered on the form"}, {temp_file, "full pathname of the temp file"} | _T] \end{verbatim} Some multipart/form messages also headers such as \verb+Content-Type+ and \verb+Content-Transfer-Encoding+ for different subparts of the message. If these headers are present in any subpart of a multipart/form message, they're also included in that subpart's parameter list, like this: \begin{verbatim} [{filename, "name of the uploaded file as entered on the form"}, {value, Contents_of_the_file_all_in_memory}, {content_type, "image/png"} | _T] \end{verbatim} Note that for the temporary file case, it's your responsibility to delete the file when you're done with it. Here's an example: \begin{verbatim} -module(my_yaws_controller). -export([out/1]). out(Arg) -> Options = [no_temp_file], case yaws_multipart:read_multipart_form(Arg, Options) of {done, Params} -> io:format("Params : ~p~n", [Params]), {ok, [{filename, FileName},{value,FileContent}|_]} = dict:find("my_file", Params), AnotherParam = dict:find("another_param", Params); %% do something with FileName, FileContent and AnotherParam {error, Reason} -> io:format("Error reading multipart form: ~s~n", [Reason]); Other -> Other end. \end{verbatim} Here, \verb+my_yaws_controller+ is a user-defined module compiled as usual with \verb+erlc+ with the resulting \verb+.beam+ file placed in the \Yaws\ load path. The module is then registered with \Yaws\ as an \emph{appmod} to allow it to receive and process requests---see section \ref{appmods} for more details. \chapter{Mode of operation} \section{On-the-fly compilation} When the client requests a \Yaws\ page, \Yaws\ will look in its caches (there is one cache per virtual server) to see if it finds the requested page in the cache. If \Yaws\ doesn't find the page in the cache, it will compile the page. This only happens the first time a page is requested. Say that the page is 400 bytes big and has the following layout: \begin{figure}[h] \begin{center} \includegraphics[scale=0.4] {layout} \end{center} \end{figure} The \Yaws\ server will then parse the file and produce a structure which makes it possible to readily deliver the page without parsing the next time the same page is requested. When shipping the page it will \begin{enumerate} \item Ship the first 100 bytes from the file \item Evaluate the first \Erlang\ chunk in the file and ship the output from the \verb+out/1+ function in that chunk. It will also jump ahead in the file and skip 120 bytes. \item Ship 80 bytes of HTML code \item Again evaluate an \Erlang\ chunk, this time the second and jump ahead 60 bytes in the file. \item And finally ship 140 bytes of HTML code to the client \end{enumerate} \Yaws\ writes the source output of the compilation into a directory \verb+/tmp/yaws/$UID+. The beam files are never written to a file. Sometimes it can be useful to look at the generated source code files, for example if the \Yaws{}\slash \Erlang\ code contains a compilation error which is hard to understand. \section{Evaluating the Yaws Code} All client requests will execute in their own \Erlang\ process. For each group of virtual hosts on the same IP:PORT pair one \Erlang\ process listens for incoming requests. This process spawns acceptor processes for each incoming request. Each acceptor process reads and parses all the HTTP headers from the client. It then looks at the \verb+Host:+ header to figure out which virtual server to use, i.e. which docroot to use for this particular request. If the \verb+Host:+ header doesn't match any server from \textit{yaws.conf} with that IP:PORT pair, the first one from \textit{yaws.conf} is chosen. By default \Yaws\ will not ship any data at all to the client while evaluating a \Yaws\ page. The headers as well as the generated content are accumulated and not shipped to the client until the entire page has been processed. \chapter{SSL} Secure Socket Layer (SSL) is a protocol used on the Web for delivering encrypted pages to the WWW client. SSL is widely deployed on the Internet and virtually all bank transactions as well as all online shopping today is done with SSL encryption. There are many good sources on the net that describe SSL in detail, so we will not try to do that here. See for example \url{http://www.tldp.org/HOWTO/SSL-Certificates-HOWTO/}, which describes how to manage certificates and keys. In order to run an SSL server we must have a certificate. Either we can create a so-called self-signed certificate ourselves or buy a certificate from one of the many CA's (Certificate Authorities) on the net. \Yaws\ uses the OTP interface to OpenSSL. To setup a \Yaws\ server with SSL we could have a \textit{yaws.conf} file that looks like: \begin{verbatim} logdir = /var/log/yaws port = 443 listen = 192.168.128.32 docroot = /var/yaws/www.funky.org keyfile = /etc/funky.key certfile = /etc/funky.cert password = gazonk \end{verbatim} This is the easiest possible SSL configuration. The configuration refers to a certificate file and a key file. The certificate file must contain the name "www.funky.org" as it "Common Name". The keyfile is the private key file and it is encrypted using the password "gazonk". \chapter{Applications} \Yaws\ is well suited for Web applications. In this chapter we will describe a number of application templates. Code and strategies that can be used to build Web applications. There are several ways of starting applications from \Yaws{}. \begin{itemize} \item The first and most easy variant is to specify the \verb+-r Module+ flag to the \Yaws\ startup script. This will \verb+apply(Module,start,[])+ \item We can also specify \verb+runmods+ in the \textit{yaws.conf} file. It is possible to have several modules specified if want the same \Yaws\ server to run several different applications. \begin{verbatim} runmod = myapp runmod = app_number2 \end{verbatim} \item It is also possible to do it the other way around, let the main application start \Yaws{}. We call this embedded mode, which we will discuss in chapter \ref{embedded}. \end{itemize} \section{Login scenarios} Many Web applications require the user to login. Once the user has logged in the server sets a cookie and then the user will be identified by help of the cookie in subsequent requests. \subsection{The session server} The cookie is passed in the headers and is available to the \Yaws\ programmer in the \verb+Arg+ \verb+#arg+ record. The \Yaws\ session server can help us to maintain a state for a user while the user is logged in to the application. The session server has the following 5 API functions to aid us: \begin{enumerate} \item \verb+yaws_api:new_cookie_session(Opaque)+ --- This function initiates a new cookie-based session. The \verb+Opaque+ data is typically some application-specific structure which makes it possible for the application to read a user state, or it can be the actual user state itself. \item \verb+yaws_api:cookieval_to_opaque(Cookie)+ --- This function maps a cookie to a session. \item \verb+yaws_api:replace_cookie_session(Cookie, NewOpaque)+ --- Replace the opaque user state in the session server with \verb+NewOpaque+. \item \verb+yaws_api:delete_cookie_session(Cookie)+ --- This function should typically be called when the user logs out or when our web application decides to automatically logout the user. \end{enumerate} All cookie-based applications are different but they have some things in common. In the following examples we assume the existence of a function \verb+myapp:auth(UserName, Passwd)+ and it returns \verb+ok+ or \verb+{error, Reason}+. Let's assume the following record: \begin{verbatim} -record(session, {user, passwd, udata = []}). \end{verbatim} The following function is a good template function to check the cookie. \begin{verbatim} get_cookie_val(CookieName, Arg) -> H = Arg#arg.headers, yaws_api:find_cookie_val(CookieName, H#headers.cookie). check_cookie(A, CookieName) -> case get_cookie_val(CookieName, A) of [] -> {error, "not logged in"}; Cookie -> yaws_api:cookieval_to_opaque(Cookie) end. \end{verbatim} We need to check all requests and make sure the session\_server has our cookie registered as an active session. Also, if a request comes in without a working cookie we want to present a login page instead of the page the user requested. Another quirky issue is that the pages necessary for display of the login page must be shipped without checking the cookie. The next sections explain how these needs can be met. \subsection{Arg rewrite} In this section we describe a feature whereby the user is allowed to rewrite the \verb+Arg+ at an early stage in the \Yaws\ server. We do that by specifying an \verb+arg_rewrite_mod+ in the \textit{yaws.conf} file. \begin{verbatim} arg_rewrite_mod = myapp \end{verbatim} Then in the \verb+myapp+ module we have: \begin{verbatim} arg_rewrite(Arg) -> OurCookieName = "myapp_sid" case check_cookie(A, OurCookieName) of {error, _} -> do_rewrite(Arg); {ok, _Session} -> %return Arg untouched Arg end. %% these pages must be shippable without a good cookie login_pages() -> ["/banner.gif", "/login.yaws", "/post_login.yaws"]. do_rewrite(Arg) -> Req = Arg#arg.req, {abs_path, Path} = Req#http_request.path, case lists:member(Path, login_pages()) of true -> Arg; false -> Arg#arg{req = Req#http_request{path = {abs_path, "/login.yaws"}}, state = Path} end. \end{verbatim} Our arg rewrite function lets all \verb+Arg+s go through untouched that either have a good cookie or belong to a set of predefined pages that are acceptable to get without being logged in. If we decide that the user must log in, we change the path of the request, thereby making the \Yaws\ server ship a login page instead of the page the user requested. We also set the original path in the \verb+Arg+ state argument so that the login page can redirect the user to the original page once the login procedure is finished. Within an arg rewrite function, examining and modifying HTTP headers can be achieved using the following functions from the \verb+yaws_api+ module: \begin{itemize} \item \verb+set_header/2+, \verb+set_header/3+ \item \verb+get_header/2+, \verb+get_header/3+ \item \verb+merge_header/2+, \verb+merge_header/3+ \item \verb+delete_header/2+ \end{itemize} All functions operate on instances of the \verb+#headers{}+ record type defined in the \verb+yaws_api.hrl+ include file. Should an arg rewrite function need to return a response for a particular request, it can do so by returning an \verb+#arg+ record instance with its \verb+state+ field set to an instance of a \verb+#rewrite_response+ record. For example, below is an arg rewrite function that allows only \verb+GET+ and \verb+POST+ requests, returning a 405 \emph{Method Not Allowed} for requests with any other HTTP method: \begin{verbatim} arg_rewrite(Arg) -> Allowed = ['GET', 'POST'], Req = yaws_api:arg_req(Arg), Method = yaws_api:http_request_method(Req), case lists:member(Method, Allowed) of true -> Arg; false -> AllowedStrs = string:join([atom_to_list(M) || M <- Allowed], ","), Arg#arg{state= #rewrite_response{ status=405, headers=[{header, {"Allow", AllowedStrs}}, {header, {connection, "close"}}]}} end. \end{verbatim} \subsection{Authenticating} Now we're approaching the \verb+login.yaws+ page, the page that displays the login prompt to the user. The login page consists of two parts: one part that displays the login data as a form, and one form processing page that reads the data the user entered in the login fields and performs the actual authentication. The login page performs a tiny well-known Web trick where it passes the original URL request in a hidden field in the login page and thereby passing that information to the form processing page. The page \verb+login.yaws+: \begin{verbatim} out(A) -> {ehtml, {html,[], [{h2, [], "Login page"}, {hr}, {form, [{action,"/login_post.yaws"}, {method,post}], [{p,[], "Username"}, {input, [{type,text},{name,uname}]}, {p,[],"Password"}, {input, [{type,password},{name,passwd}]}, {input, [{type,submit},{value,"Login"}]}, {input, [{type,hidden},{name,url}, {value, A#arg.state}]}]}]}}. \end{verbatim} The form processing page which gets the \verb+POST+ data from the code above: \begin{verbatim} -include("myapp.hrl"). %% we have the session record there %% we must set the include_path in the yaws.conf file %% in order for the compiler to find that file kv(K,L) -> {value, {K, V}} = lists:keysearch(K,1,L), V. out(A) -> L = yaws_api:parse_post(A), User = kv(user, L), Pwd = kv(passwd, L), case myapp:auth(User, Pwd) of ok -> S = #session{user = User, passwd = Pwd, udata = []}, %% Now register the session to the session server Cookie = yaws_api:new_cookie_session(S), [{redirect_local, kv(url, L)}, yaws_api:set_cookie("myapp_sid",Cookie,[])] Err -> {ehtml, {html, [], {p, [], f("Bad login: ~p",[Err])}}} end. \end{verbatim} The function returns a list of two new (not previously discussed) return values: instead of returning HTML output as in \verb+{html, Str}+ or \verb+{ehtml,Term}+ we return a list of two new values. (There are many different possible return values from the \verb+out/1+ function and they will all be described later.) The two new values are: \begin{enumerate} \item The tuple \verb+{redirect_local, Path}+ makes the \Yaws\ web server return a 302 redirect to the specified \verb+Path+. Optionally a different status code can be supplied which will be used in place of 302, e.g. \verb+{redirect_local, Path, 307}+. \item \verb+yaws_api:set_cookie("myapp_sid",Cookie,[])+ generates a \verb+Set-Cookie+ header. \end{enumerate} Now if we put all this together we have a full-blown cookie-based login system. The last thing we did in the form processing code was to register the session with the session server thereby letting any future requests go straight through the \verb+Arg+ rewriter. This way both \Yaws\ pages as well as all or some static content is protected by the cookie login code. \subsection{Database driven applications} We can use code similar to the code in the previous section to associate a user session to entries in a database. Mnesia fits perfectly together with \Yaws\ and keeping user persistent state in Mnesia is both easy and convenient. Once the user has logged in we can typically use the user name as key into the database. We can mix \verb+ram_tables+ and \verb+disc_tables+ to our liking. The Mnesia database must be initialized via \verb+create_table/2+ before it can be used. This is typically done while installing the web application on a machine. Another option is to let the application check that Mnesia is initialized whenever the application starts. If we don't want or need to use Mnesia, it's of course possible to use a simple \verb+dets+ file or a text file as well. \section{Appmods} \label{appmods} Appmods is mechanism to invoke different applications based upon the URL. A URL---as presented to the web server in a request---has a path part and a query part. It is possible to install several appmods in the \textit{yaws.conf} file as shown below: \begin{verbatim} appmods = foo myapp \end{verbatim} Now, if the user requests a URL where any component in the directory path is an appmod, the parsing of the URL will terminate there and instead of reading the actual file from the disk, \Yaws\ will invoke the appmod with the remainder of the path inserted into \verb+Arg#arg.appmoddata+. Say the user requests the URL \url{http://www.funky.org/myapp/xx/bar.html}. \Yaws\ will not ship the file \verb+bar.html+ to the client, instead it will invoke \verb+myapp:out(Arg)+ with \verb+Arg#arg.appmoddata+ set to the string \verb+xx/bar.html+. Any optional query data---that is, data that follows the first '?' character in the URL---is removed from the path and passed as \verb+Arg#arg.querydata+. Appmods can be used to run applications on a server. All requests to the server that has an appmod in the URL will be handled by that application. If the application decides that it want to ship a page from the disk to the client, it can return the tuple \verb+{page, Path}+. This return value will make \Yaws\ read the page from the disk, possibly add the page to its cache of commonly accessed pages and ship it back to the client. The \verb+{page, Path}+ return value is equivalent to a redirect, but it removes an extra round trip, and is thus faster. Appmods can also be used to fake entire directory hierarchies that don't exist on disk. \section{The opaque data} Sometimes an application needs application-specific data such as the location of its data files. There exists a mechanism to pass application-specific configuration data from the \Yaws\ server to the application. When configuring a server we have an opaque field in the configuration file that can be used for this purpose. Say we have the following fields in the config file: \begin{verbatim} listen = 192.168.128.44 foo = bar somefile = /var/myapp/db myname = hyber \end{verbatim} This will create a normal server that listens to the specified IP address. An application has access to the opaque data that was specified in that particular server through \verb+Arg#arg.opaque+. If we have the opaque data specified above, the \verb+Arg+ opaque field will have the value: \begin{verbatim} [{foo, "bar"}, {somefile, "/var/myapp/db"}, {myname, "hyber"} ] \end{verbatim} \section{Customizations} When actually deploying an application at a live site, some of the standard \Yaws\ behaviors are not acceptable. Many sites want to customize the web server behavior when a client requests a page that doesn't exist on the web server. The standard \Yaws\ behavior is to reply with status code 404 and a message explaining that the page doesn't exist. Similarly, when \Yaws\ code crashes, the reason for the crash is displayed in the Web browser. This is very convenient while developing a site but not acceptable in production. \subsection{404 File not found} We can install a special handler for 404 messages. We do that by specifying a \verb+errormod_404+ in the \textit{yaws.conf} file. If we have: \begin{verbatim} .. .. .. errormod_404 = myapp \end{verbatim} When \Yaws\ gets a request for a file that doesn't exist, it invokes the \verb+errormod_404+ module to generate both the status code as well as the content of the message. If \verb+Module+ is specified as the \verb+errormod_404+ module, \Yaws\ will invoke \verb+Module:out404(Arg, GC, SC)+, passing the arguments as described below: \begin{itemize} \item \verb+Arg+ is an \verb+#arg{}+ record \item \verb+GC+ is a \verb+#gconf{}+ record (defined in \verb+yaws.hrl+) \item \verb+SC+ is a \verb+#sconf{}+ record (defined in \verb+yaws.hrl+) \end{itemize} The function can and must do the same things that a normal \verb+out/1+ function does. \subsection{Crash messages} We use a similar technique for generating the crash messages: we install a module in the \textit{yaws.conf} file and let that module generate the crash message. We have: \begin{verbatim} errormod_crash = Module \end{verbatim} The default is to display the entire formatted crash message in the browser. This is good for debugging but not good for production. If \verb+Module+ is specified as the \verb+errormod_crash+ module, the function \verb+Module:crashmsg(Arg, SC, Str)+ will be called. The \verb+Str+ argument is the real crash message formatted as a string. \section{Stream content} If the \verb+out/1+ function returns the tuple \verb+{content, MimeType, Content}+ \Yaws\ will ship that data to the Client. This way we can deliver dynamically generated content to the client which is of a different MIME type than "text/html". If the generated response is very large and it not possible or practical to generate the whole thing, we can return the value: \begin{verbatim} {streamcontent, MimeType, FirstChunk} \end{verbatim} \noindent which delivers data back to the client using HTTP chunked transfer (see RFC 2616 section 3.6.1) and then from a different \Erlang\ process deliver the remaining chunks by using the functions described below: \begin{enumerate} \item \verb+yaws_api:stream_chunk_deliver(YawsPid, Data)+ where the \verb+YawsPid+ is the process id of the \Yaws\ worker process. That pid is available in \verb+Arg#arg.pid+. \item \verb+stream_chunk_end(YawsPid)+ which must be called to indicate the end of the stream. \end{enumerate} A streaming alternative is also available for applications that need a more direct way to deliver data to clients, such as those dealing with data too large to buffer in memory but not wishing to use chunked transfer, or applications that use long-polling (Comet) techniques that require them to hold client connections open for extended periods. For these situations we can return the value: \begin{verbatim} {streamcontent_from_pid, MimeType, Pid} \end{verbatim} \noindent to tell \Yaws\ we wish to deliver data of MIME type \verb+MimeType+ to the client from process \verb+Pid+. In this case, \Yaws\ will prepare the socket for delivery from \verb+Pid+ and then send one of the following messages to \verb+Pid+: \begin{itemize} \item \verb+{ok, YawsPid}+ tells \verb+Pid+ that it is now OK to proceed with sending data back to the client using the socket. The socket is accessible as \verb+Arg#arg.clisock+. \item \verb+{discard, YawsPid}+ informs \verb+Pid+ that it should not attempt to use the socket, typically because the requested HTTP method requires no response body. \end{itemize} We call one of the following functions to send data: \begin{itemize} \item \verb+yaws_api:stream_process_deliver(Socket, IoList)+ sends data \verb+IoList+ using socket \verb+Socket+ without chunking the data. To ensure chunking is not in effect, return \begin{verbatim} {header, {transfer_encoding, erase}} \end{verbatim} in a list with the \verb+streamcontent_from_pid+ directive (which must always be last in such a list). \item \verb+yaws_api:stream_process_deliver_chunk(Socket, IoList)+ sends data \verb+IoList+ using socket \verb+Socket+ but converts the data into chunked transfer form before sending it. \end{itemize} Pids using chunked transfer must indicate the end of their transfer by calling the following function: \begin{itemize} \item \verb+yaws_api:stream_process_deliver_final_chunk(Socket, IoList)+ \end{itemize} which delivers a special HTTP chunk to mark the end of the data transfer to the client. Finally, \verb+Pid+ must always call \verb+yaws_api:stream_process_end(Socket, YawsPid)+ when it finishes sending data or when it receives the \verb+{discard, YawsPid}+ message from \Yaws\ --- this is required to inform \Yaws\ that \verb+Pid+ has finished with the socket and will not use it directly anymore. If the application has to close the socket while it's in control of it, though, it must pass the atom \verb+closed+ as the first argument to \verb+yaws_api:stream_process_end+ in place of the socket to inform \Yaws\ that the socket has been closed and it should no longer attempt to use it. App\-li\-ca\-tions that use the \verb+streamcontent_from_pid+ directive that also want to a\-void chunked transfer encoding for their streams should be sure to include a set\-ting for the \verb+Content-Length+ header in their \verb+out/1+ return value. \Yaws\ au\-to\-mat\-i\-cal\-ly sets the \verb+Transfer-Encoding+ head\-er to \verb+chunked+ if it does not detect a \verb+Content-Length+ header. \section{All out/1 return values} \begin{itemize} \item \verb+{html, DeepList}+ This assumes that \verb+DeepList+ is formatted HTML code. The code will be inserted in the page. \item \verb+{ehtml, Term}+ This will transform the \Erlang\ term \verb+Term+ into a stream of HTML content. \item \verb+{exhtml, Term}+ This will transform the \Erlang\ term \verb+Term+ into a stream of strict XHTML code. \item \verb+{content, MimeType, Content}+ This function will make the web server generate different content than HTML. This return value is only allowed in a \Yaws\ file which has only one \verb+ + part and no html parts at all. \item \verb+{streamcontent, MimeType, FirstChunk}+ This return value plays the same role as the \verb+content+ return value above. However it makes it possible to stream data to the client using HTTP chunked transfer if the \Yaws\ code doesn't have access to all the data in one go. (Typically if a file is very large or if data arrives from back end servers on the network.) \item \verb+{streamcontent_with_timeout, MimeType, FirstChunk, Timeout}+ Similar to the above, but with an explicit timeout. The default timeout is 30 secs, i.e. if the application fails to deliver data to the \Yaws\ process, the streaming will stop. This is often not the desired behaviour in Comet/Ajax applications. It's possible to provide 'infinity' as the timeout. \item \verb+{streamcontent_from_pid, MimeType, Pid}+ This return value is similar to the \verb+streamcontent+ return value above. However it makes it possible to stream data to the client directly from an application process to the socket. This approach can be useful for applications that employ long-polling (Comet) techniques, for example, and for applications wanting to avoid buffering data or avoid HTTP chunked mode transfer for streamed data. \item \verb+{streamcontent_with_size, Sz, MimeType, Pid}+ This is similar to the \verb+streamcontent+ return value above. However it makes it possible to stream data to the client by setting the content length of the response. As the opposite of other ways to stream data, in this case, the response is not chunked encoded. \item \verb+{header, H}+ Accumulates a HTTP header. The trailing CRNL which is supposed to end all HTTP headers must NOT be added. It is added by the server. The following list of headers are given special treatment. \begin{itemize} \item \verb+{connection, What}+ - This sets the Connection: header. If \textit{What} is the special value \textit{\"close\"}, the connection will be closed once the yaws page is delivered to the client. \item \verb+{server, What}+ - Sets the \textit{Server:} header. By setting this header, the server's signature will be dynamically overloaded. \item \verb+{location, What}+ - Sets the \textit{Location:} header. This header is typically combined with the \textit{\{status, 302\}} return value. \item \verb+{cache_control, What}+ - Sets the \textit{Cache-Control:} header. \item \verb+{expires, What}+ - Sets the \textit{Expires:} header. \item \verb+{date, What}+ - Sets the \textit{Date:} header. \item \verb+{allow, What}+ - Sets the \textit{Allow:} header. \item \verb+{last_modified, What}+ - Sets the \textit{Last-Modified:} header. \item \verb+{etag, What}+ - Sets the \textit{Etag:} header. \item \verb+{set_cookie, What}+ - Prepends a \textit{Set-Cookie:} header to the list of previously set \textit{Set-Cookie} headers. \item \verb+{content_range, What}+ - Sets the \textit{Content-Range:} header. \item \verb+{content_type, What}+ - Sets the \textit{Content-Type:} header. \item \verb+{content_encoding, What}+ - Sets the \textit{Content-Encoding:} header. If this header is defined, no deflate is performed by \Yaws\. So you can compress data by yourself. \item \verb+{content_length, What}+ - Normally \Yaws\ will ship Yaws pages using \textit{Transfer-Encoding: chunked}. This is because we generally can't know how long a yaws page will be. If we for some reason want to force a \textit{Content-Length:} header (and we actually do know the length of the content, we can force yaws to not ship the page chunked. \item \verb+{transfer_encoding, What}+ - Sets the \textit{Transfer-Encoding:} header. \item \verb+{www_authenticate, What}+ - Sets the \textit{WWW-Authenticate:} header. \item \verb+{vary, What}+ - Sets the \textit{Vary:} header. \end{itemize} All other headers must be added using the normal HTTP syntax. Example: \begin{verbatim} {header, {"My-X-Header", "gadong"}} or {header, "My-X-Header: gadong"} \end{verbatim} \item \verb+{header, {H, erase}}+ A specific case of the previous directive; use this to remove a specific header from a response. For example, streaming applications and applications using server-sent events (see \url{http://www.w3.org/TR/eventsource/ }) should use \verb+{header, {transfer_encoding, erase}}+ to turn off chunked encoding for their responses. \item \verb+{allheaders, HeaderList}+ Will clear all previously accumulated headers and replace them. \item \verb+{status, Code}+ Sets the response HTTP status code to \verb+Code+. \item \verb+break+ Will stop processing of any consecutive chunks of erl or HTML code in the \Yaws\ file. \item \verb+ok+ Do nothing. \item \verb+flush+ Flush remaining data sent by the client. \item \verb+{redirect, Url}+ Erase all previous headers and accumulate a single HTTP \verb+Location+ header. Set the status code to 302. \item \verb+{redirect, Url, Status}+ Same as redirect above with the additional option of supplying the status code. The default for a redirect is 302 but 301, 303 and 307 are also valid redirect status codes. \item \verb+{redirect_local, Path}+ Does a redirect to the same \url{Scheme://Host:Port/Path} in which we are currently executing. \verb+Path+ can be either be the path directly (equivalent to \verb+abs_path+), or one of \verb+{{abs_path, Path}+ or \verb+{{rel_path, RelativePath}}+ \item \verb+{redirect_local, Path, Status}+ Same as \verb+redirect_local+ above with the additional option of supplying the status code. The default for a redirect is 302 but 301, 303 and 307 are also valid redirect status codes. \item \verb+{get_more, Cont, State}+ When we are receiving large \verb+POST+s we can return this value and be invoked again when more data arrives. \item \verb+{page, Page}+ Make \Yaws\ returns a different local page than the one being requested. \verb+Page+ is a Request-URI, so it must be url-encoded and can contain a query-string. \item \verb+{page, {Options, Page}}+ Like the above, but supplying an additional deep list of options. Supported options types are: \begin{itemize} \item \verb+{status, C}+ - Set the HTTP response status code \verb+C+ for page \verb+Page+. \item \verb+{header, H}+ - Accumulate the HTTP header \verb+H+ for page \verb+Page+. \item \verb+{disable_cache, Bool}+ - if set to \verb+true+, disable the cache of \verb+Page+ for this call. \end{itemize} \item \verb+{websocket, CallbackModule, Options}+ Tell \Yaws\ to use \verb+CallbackModule+ as a WebSockets Protocol handler for traffic on the client socket. See chapter \ref{websockets} for more details. \item \verb+[ListOfValues]+ It is possible to return a list of the above defined return values. Any occurrence of the atoms \verb+streamcontent+, \verb+streamcontent_with_timeout+, \verb+streamcontent_with_size+,\\ \verb+streamcontent_from_pid+, \verb+get_more+, \verb+page+ or \verb+break+ in this list is legal only if it is the last position of the list. If not, remaining values in the list are ignored. \end{itemize} \chapter{Debugging and Development} \Yaws\ has excellent debugging capabilities. First and foremost we have the ability to run the web server in interactive mode by means of the command line switch \verb+-i+, which gives us a regular \Erlang\ command line prompt we can use to compile helper code or reload helper code. Furthermore all error messages are displayed there. If a \verb+.yaws+ page producees any regular \Erlang\ I\slash O, that output will be displayed at the \Erlang\ prompt, assuming we are running in interactive mode. If we give the command line switch \verb+-d+ we get some additional error messages. Also \Yaws\ does some additional checking of user supplied data such as headers. \section{Logs} \Yaws\ produces various logs. All log files are written into the \Yaws\ logdir directory. This directory is specified in the config file. We have the following log files: \begin{itemize} \item The access log. Access logging is turned on or off per server in the \textit{yaws.conf} file. If access\_log is turned on for a server, \Yaws\ will produce a log in Common Access Log Format called \textit{HostName:PortNumber.access} \item The auth log. Auth logging is turned on or off per server in the \textit{yaws.conf} file. If auth\_log is turned on for a server, \Yaws\ will produce a log called \textit{HostName:PortNumber.auth} which contains all HTTP auth-related messages. \item \textit{report.log} This file contains all error and crash messages for all virtual servers in the same file. \item Trace files. The two command line flags \verb+-t+ and \verb+-T+ tells \Yaws\ to trace all traffic or just all HTTP messages and write them to files. \end{itemize} \chapter{External scripts via CGI} \Yaws\ can also interface to external programs generating dynamic content via the Common Gateway Interface (CGI). This has to be explicitly enabled for a virtual host by listing \verb+cgi+ in the \verb+allowed_scripts+ line in the configuration file. Any request for a page ending in \verb+.cgi+ (or \verb+.CGI+) will then result in trying to execute the corresponding file. If you have a PHP executable compiled for using CGI in the \verb+PATH+ of the \Yaws\ server, you can enable PHP support by adding \verb+php+ to \verb+allowed_scripts+. Requests for pages ending in \verb+.php+ will then result in \Yaws\ executing \verb+php+ (configurable via \verb+php_handler+) and passing the name of the corresponding file to it via the appropriate environment variable. These ways of calling CGI scripts are also available to \verb+.yaws+ scripts and appmods via the functions \verb+yaws_api:call_cgi/2+ and \verb+yaws_api:call_cgi/3+. This makes it possible to write wrappers for CGI programs, irrespective of the value of \verb+allowed_scripts+. The author of this \Yaws\ feature uses it for self-written CGI programs as well as for using a standard CGI package. You should not be surprised however, should some scripts not work as expected due to an incomplete or incorrect implementation of certain CGI meta-variables. The author of this feature is interested in hearing about your experiences with it. He can be contacted at \verb+carsten@codimi.de+. \chapter{FastCGI} \Yaws\ supports the responder role and the authorizer role of the FastCGI protocol. See \verb+www.fastcgi.com+ for details on the FastCGI protocol. The benefits of using FastCGI include: \begin{enumerate} \item Unlike CGI, it is not necessary to spawn a new process for every request; the application server can handle multiple requests in a single process. \item The fact that the application server can run on a different computer benefits scalability and security. \item The application server can be written in any language for which a FastCGI library is available. Existing applications which have been written for other web servers can be used with \Yaws{}. \item FastCGI can also be used to implement external authentication servers (in addition to generating dynamic content). \end{enumerate} Support for FastCGI was added to \Yaws\ by Bruno Rijsman (\verb+brunorijsman@hotmail.com+). \section{The FastCGI Responder Role} The FastCGI responder role allows \Yaws\ to communicate with an application server running on a different (or on the same) computer to generate dynamic content. The FastCGI protocol (which runs over TCP) is used to send the request information from \Yaws\ to the application server and to send the response information (e.g. the generated dynamic content) from the application server back to \Yaws{}. FastCGI responders can be invoked in two ways: \begin{enumerate} \item By including \verb+fcgi+ in the \verb+allowed_scripts+ line in the configuration file (note that the default value for \verb+allowed_scripts+ includes \verb+fcgi+). In this case a request for any resource with the \verb+.fcgi+ extension will result in a FastCGI call to the application server to dynamically generate the content. Note: the \Yaws\ server will only call the application server if a file corresponding to the resource name (i.e. a file with the \verb+.fcgi+ extension) exists locally on the \Yaws\ server. The contents of that file are not relevant. \item By creating an appmod which calls \verb+yaws_api:call_fcgi_responder+. See the \verb+yaws_api(5)+ man page for details. \end{enumerate} \section{The FastCGI Authorizer Role} The FastCGI authorizer role allows \Yaws\ to communicate with an authentication server to authenticate requests. The FastCGI protocol is used to send the request information from \Yaws\ to the authentication server and the authentication response back from the authentication server to \Yaws{}. If access is allowed, \Yaws\ proceeds to process the request normally. If access is denied, the authentication server provides the response which is sent back to the client. This is typically a ``not authorized'' response or a redirect to a login page. FastCGI authorizers are invoked by creating an appmod which calls \verb+yaws_api:call_fcgi_authorizer+. See the \verb+yaws_api(5)+ man page for details. \section{The FastCGI Filter Role} FastCGI defines a third role, the filter role, which \Yaws\ does not currently support. \section{FastCGI Configuration} The following commands in the \textit{yaws.conf} file control the operation of FastCGI. If you use FastCGI, you \emph{must} include the \verb+fcgi_app_server+ setting in the configuration file to specify the host name (or IP address) and TCP port of the FastCGI application server. You may include the \verb+fcgi_trace_protocol+ setting to enable or disable tracing of FastCGI protocol messages. This is useful for debugging. You may include the \verb+fcgi_log_app_error+ setting to enable or disable logging application errors (any output to stderr and non-zero exit codes). You may include the \verb+extra_cgi_vars+ command to pass additional environment variables to the application. \chapter{Security} \Yaws\ is of course susceptible to intrusions. \Yaws\ has the ability to run under a different user than root, even if we need to listen to privileged port numbers. Running as root is generally a bad idea. Intrusions can happen basically at all places in \Yaws\ code where the \Yaws\ code calls either the BIF \verb+open_port+ or when \Yaws\ code calls \verb+os:cmd/1+. Both \verb+open_port+ and \verb+os:cmd/1+ invoke the \verb+/bin/sh+ interpreter to execute its commands. If the commands are nastily crafted bad things can easily happen. All data that is passed to these two function must be carefully checked. Since \Yaws\ is written in \Erlang\ a large class of cracks are eliminated since it is not possible to perform any buffer overrun cracks on a \Yaws\ server. This is very good. Another possible point of entry to the system is by providing a URL which takes the client out from the docroot. This should not be possible -- and the impossibility relies on the correctness of the URL parsing code in \Yaws{}. \section{WWW-Authenticate} \Yaws\ has support for WWW-Authentication. WWW-Authenticate is a standard HTTP scheme for the basic protection of files with a username and password. When a client browser wants a protected file, it must send a \verb+Authenticate: username:password+ header in the request. Note that this is plain text. If there is no such header or the username and password is invalid the server will respond with status code 401 and the realm. Browsers will then tell the user that a username and password is needed for ``realm'', and will resend the request after the user enters the information. WWW-Authentication is configured in the \textit{yaws.conf} file, in as many \textit{} directives as you desire: \begin{verbatim} docroot = /var/yaws/www/ .. .. realm = secretpage dir = /protected dir = /anotherdir user = klacke:gazonk user = jonny:xyz user = ronny:12r8uyp09jksfdge4 \end{verbatim} \Yaws\ will require one of the given username:password pairs for all files in the \textit{/protected} and \textit{/anotherdir} directories. Note that these directories are specified as a server path, that is, the filesystem path that is actually protected here is \textit{/var/yaws/www/protected} . \chapter {Embedded mode} \label{embedded} \Yaws\ is a normal OTP application. It is possible to integrate \Yaws\ into another larger application. The \Yaws\ source tree must be integrated into the larger application's build environment. \Yaws\ is then simply started by \verb+application:start()+ from the larger application's boot script, or the \Yaws\ components needed for the larger application can be started individually under the application's supervisor(s). By default \Yaws\ reads its configuration data from a config file, the default is \textit{/usr/local/etc/yaws/yaws.conf} . If \Yaws\ is integrated into a larger application, however, that application typically has its configuration data kept at some other centralized place. Sometimes we may not even have a file system to read the configuration from if we run a small embedded system. \Yaws\ reads its application environment. If the environment key \verb+embedded+ is set to \verb+true+, \Yaws\ starts in embedded mode. Once started it must be fed a configuration, and that can be done after \Yaws\ has started by means of the function \verb+yaws_api:setconf/2+. It is possible to call \verb+setconf/2+ several times to force \Yaws\ to reread the configuration. \section{Creating Global and Server Configurations} The \verb+yaws_api:setconf/2+ function mentioned in the previous section takes two arguments: \begin{itemize} \item a \verb+#gconf+ record instance, specifying global \Yaws\ configuration \item a list of lists of \verb+#sconf+ record instances, each specifying configuration for a particular server instance \end{itemize} These record types are specified in \verb+yaws.hrl+, which is not normally intended for inclusion by applications. Instead, \Yaws\ provides the \verb+yaws_api:embedded_start_conf/1,2,3,4+ functions that allow embedded mode applications to specify configuration data using property lists (lists of \verb+{key, value}+ pairs). The \verb+yaws_api:embedded_start_conf+ functions all return a tuple containing the following four items: \begin{itemize} \item the atom \verb+ok+. \item a list of lists of \verb+#sconf+ record instances. This variable is intended to be passed directly to\\* \verb+yaws_api:setconf/2+ as its second argument. \item a \verb+#gconf+ record instance. This variable is intended to be passed directly to \verb+yaws_api:setconf/2+ as its first argument. \item a list of supervisor child specification for the \Yaws\ components the embedded mode application's configuration specified should be started. This allows embedded mode applications to start \Yaws\ under its own supervisors. \end{itemize} Note that \verb+yaws_api:embedded_start_conf+ does not actually start any servers, but rather it only returns the configuration information and child specifications needed for the embedded mode application to start and configure \Yaws\ itself. If you have difficulty figuring out how to set up your \verb+#gconf+ or \verb+#sconf+ records for embedded mode, you should first consider getting something running in non-embedded mode using a \verb+yaws.conf+ file. Once you're satisfied with the setup and \Yaws\ is running, execute the following command: \begin{verbatim} yaws --running-config \end{verbatim} This command will show the \Yaws\ configuration from your \verb+yaws.conf+ file in terms of \verb+#gconf+ and \verb+#sconf+ records, thus showing you how to set up those records for embedded mode. \section{Starting Yaws in Embedded Mode} An embedded mode application can start \Yaws\ in one of two ways: \begin{itemize} \item It can call \verb+yaws_api:embedded_start_conf+ to obtain configuration and \Yaws\ startup information as described in the previous section, start \Yaws\ under its own supervisors, and then pass the global and server configuration settings to \verb+yaws_api:setconf/2+. \item It can call \verb+yaws:start_embedded/1,2,3,4+, each of which takes exactly the same arguments as the corresponding \verb+yaws_api:embedded_start_conf/1,2,3,4+ function. Instead of just returning start and configuration information, however, \verb+yaws:start_embedded+ also starts and configures \Yaws{}, which can be more convenient but does not allow the embedded mode application any supervision control over \Yaws{}. \end{itemize} Both of these functions take care of setting the environment key \verb+embedded+ to \verb+true+. Neither approach requires any special settings in the embedded mode application's \textit{.app} file nor any special command-line switches to the \Erlang\ runtime. For an example of how to use \verb+yaws_api:embedded_start_conf+ along with \verb+yaws_api:setconf+, please see the files \verb+www/ybed_sup.erl+ and \verb+www/ybed.erl+ in the \Yaws\ distribution. \chapter{The config file - yaws.conf} In this section we provide a complete listing of all possible configuration file options. The configuration contains two distinct parts: a global part which affects all the virtual hosts and a server part where options for each virtual host is supplied. \section{Global Part} \begin{itemize} \item \verb+logdir = Directory+ --- All \Yaws\ logs will be written to files in this directory. There are several different log files written by \Yaws{}. \begin{itemize} \item \verb+report.log+ --- this is a text file that contains all error logger printouts from \Yaws{}. \item \verb+.access+ --- for each virtual host served by \Yaws{}, a file \verb+.access+ will be written which contains an access log in NCSA combined/XLF/ELF log format. \item \verb+.auth+ --- for each virtual host served by \Yaws{}, a file \verb+.auth+ will be written which contains all HTTP auth related messages. \item \verb+trace_+ - Trace files are written in this subdirectory, suffixed by the creation date. \begin{itemize} \item \verb+trace..http+ - this file contains the HTTP trace if that is enabled, where \verb+Pid+ is the process id handling the TCP connection. \item \verb+trace..traffic+ - this file contains the traffic trace if that is enabled, where \verb+Pid+ is the process id handling the TCP connection. \end{itemize} \end{itemize} Note that \verb+.access+ and \verb+.auth+ files will be used only if the directive \verb+logger_mod+ is not set or set to \verb+yaws_log+. The default value for logdir is "." \item \verb+ebin_dir = Directory+ --- This directive adds Directory to the \Erlang\ search path. It is possible to have several of these command in the configuration file. \item \verb+src_dir = Directory+ --- This directive defines a Directory as a \textit{source} directory. \Yaws\ will compile all erlang modules found in this directory and all its subdirectories. The compilation occurs when the configuration is loaded or reloaded. The \verb+include_dir+ directives are used to search for includes files. Multiple \verb+src_dir+ directives may be used. There is no such directory configured by default. \item \verb+id = String+ --- It is possible to run multiple Yaws servers on the same machine. We use the id of a Yaws server to control it using the different control commands such as: \begin{verbatim} # /usr/local/bin/yaws --id foobar --stop \end{verbatim} To stop the Yaws server with id "foobar". Each \Yaws\ server will write its internal data into a file called \$HOME/.yaws/yaws/ID where ID is the identity of the server. Yaws also creates a file called \$HOME/.yaws/yaws/ID/CTL which contains the port number where the server is listening for control commands. The default id is "default". \item \verb+server_signature = String+ --- This directive sets the "Server: " output header to the custom value. The default value is "yaws/VSN, Yet Another Web Server". \item \verb+include_dir = Directory+ --- This directive adds Directory to the path of directories where the \Erlang\ compiler searches for include files. We need to use this if we want to include \textit{.hrl} files in our \Yaws\ \Erlang\ code. \item \verb+max_num_cached_files = Integer+ --- \Yaws\ will cache small files such as commonly accessed GIF images in RAM. This directive sets a maximum number on the number of cached files. The default value is 400. \item \verb+max_num_cached_bytes = Integer+ --- This directive controls the total amount of RAM which can maximally be used for cached RAM files. The default value is 1000000, 1 megabyte. \item \verb+max_size_cached_file = Integer+ --- This directive sets a maximum size on the files that are RAM cached by \Yaws{}. The default value is 8000 bytes. \item \verb+cache_refresh_secs = Integer+ --- The RAM cache is used to serve pages that sit in the cache. An entry sits in cache at most cache\_refresh\_secs number of seconds. The default is 30. This means that when the content is updated under the docroot, that change doesn't show until 30 seconds have passed. While developing a \Yaws\ site, it may be convenient to set this value to 0. If the debug flag (\textit{-d}) is passed to the \Yaws\ start script, this value is automatically set to 0. \item \verb+trace = traffic | http+ --- This enables traffic or HTTP tracing. Tracing is also possible to enable with a command line flag to \Yaws{}. \item \verb+use_old_ssl = true | false+ --- This re-enables the old OTP SSL implementation. By default we use the new SSL implementation. \item \verb+auth_log = true | false+ --- \textit{Deprecated and ignored. Now, this target must be set in server part}. \item \verb+max_connections = nolimit | Integer+ --- This value controls the maximum number of connections from HTTP clients into the server. This is implemented by closing the last socket if the threshold is reached. \item \verb+keepalive_maxuses = nolimit | Integer+ --- Normally, \Yaws\ does not restrict the number of times a connection is kept alive using keepalive. Setting this parameter to an integer \verb+X+ will ensure that connections are closed once they have been used \verb+X+ times. This can be a useful to guard against long-running connections collecting too much garbage in the \Erlang\ VM. \item \verb+process_options = undefined | Proplist+ --- Set process spawn options for client acceptor processes. Options must be specified as a quoted string of either the atom \verb+undefined+ or as a proplist of valid process options. The supported options are \verb+fullsweep_after+, \verb+min_heap_size+, and \verb+min_bin_vheap_size+, each taking an associated integer value. Other process options are ignored. The proplist may also be empty. See \verb+erlang:spawn_opt/4+ for details on these options. \item \verb+large_file_chunk_size = Integer+ --- Set the chunk size used by \Yaws\ to send large files when sendfile is not supported or disabled. The default value is 10240. \item \verb+large_file_sendfile = erlang | yaws | disable+ --- Set the version of sendfile method to use to send large files (if supported): \begin{itemize} \item \verb+erlang+ --- use \textit{file:sendfile/5}, if supported. \item \verb+yaws+ --- use Yaws sendfile linked-in driver, if supported. \item \verb+disable+ --- do not use any sendfile method, but \textit{gen\_tcp:send/2}. \end{itemize} The default value is yaws. \item \verb+acceptor_pool_size = Integer+ --- Set the size of the pool of cached acceptor processes. The specified value must be greater than or equal to 0. The default value is 8. Specifying a value of 0 effectively disables the process pool. \item \verb+log_wrap_size = Integer+ --- The logs written by \Yaws\ are all wrap logs, the default value at the size where they wrap around and the original gets renamed to File.old is 1000000, 1 megabyte. This value can changed. If we set the value to 0 the logs will never wrap. If we want to use \Yaws\ in combination with a more traditional log wrapper such as logrotate, set the size to 0 and \Yaws\ will reopen the logfiles once they have be renamed/removed. \item \verb+log_resolve_hostname = true | false+ --- By default the client host IP is not resolved in the access logs. \item \verb+fail_on_bind_err = true | false+ --- Fail completely or not if \Yaws\ fails to bind a listen socket Default is true. \item \verb+soap_srv_mods = ListOfModuleSetting+ --- If \verb+enable_soap+ is true, a startup \Yaws\ will invoke \verb+yaws_soap_srv:setup()+ to setup modules set here. \verb+ModuleSetting+ is either a triad like\\ \verb++ or a tetrad like \verb++\\ which specifies the prefix. A prefix will be used as argument of \verb+yaws_soap_lib:initModel()+ and then be used as a XML namespace prefix. Note, the WsdlFile here should be an absolute-path file in local file systems. For example, we can specify \begin{verbatim} soap_srv_mods= \end{verbatim} \item \verb+php_exe_path = Path+ --- \textit{this target is deprecated and useless. use 'php\_handler' target in server part instead}. The name of (and possibly path to) the php executable used to interpret php scripts (if allowed). Default is php-cgi. \item \verb+copy_error_log = true | false+ --- Enable or disable copying of the error log. When we run in embedded mode, there may very well be some other systems process that is responsible for writing the errorlog to a file whereas when we run in normal standalone mode, we typically want the Erlang errorlog written to a report.log file. Default value is true. \item \verb+ysession_mod = Module+ --- Allows to specify a different \Yaws\ session storage mechanism instead of an ETS table. One of the drawbacks of the default \verb+yaws_session_server+ implementation is that server side cookies are lost when the server restarts. Specifying a different module here will pass all write/read operations to this module (it must implement appropriate callbacks). \item \verb+runmod = ModuleName+ --- At startup \Yaws\ will invoke \verb+ModuleName:start()+ in a separate process. It is possible to have several runmods. This is useful if we want to reuse the Yaws startup shell script for our own application. \item \verb+pick_first_virthost_on_nomatch = true | false+ --- When \Yaws\ gets a request, it extracts the Host: header from the client request to choose a virtual server amongst all servers with the same IP/Port pair. This configuration parameter decides whether Yaws should pick the first (as defined in the yaws.conf file) if no name match or not. In real live hosting scenarios we typically want this to be false whereas in testing/development scenarios it may be convenient to set it to true. Default is true. \item \verb+keepalive_timeout = Integer | infinity+ --- If the HTTP session will be kept alive (i.e., not immediately closed) it will close after the specified number of milliseconds unless a new request is received in that time. The default value is 30000. The value \verb+infinity+ is legal but not recommended. \item \verb+subconfig = File+ --- Load specified config file. Absolute paths or relative ones to the configuration location are allowed. Unix-style wildcard strings can be used to include several files at once. See \verb+filelib:wildcard/1+ for details. Hidden files, starting by a dot, will be ignored. For example: \begin{verbatim} subconfig = /etc/yaws/global.conf subconfig = /etc/yaws/vhosts/*.conf \end{verbatim} Or, relatively to the configuration location: \begin{verbatim} subconfig = global.conf subconfig = vhosts/*.conf \end{verbatim} \textbf{WARNING: because of a bug in filelib:wildcard/2, wildcard strings are forbidden for Erlang/OTP R15B03 and previous.} \item \verb+subconfigdir = Directory+ --- Load all config files found in the specified directory. The given Directory can be an absolute path or relative to the configuration location. Hidden files, starting by a dot, will be ignored. \item \verb+x_forwarded_for_log_proxy_whitelist = ListOfUpstreamProxyServerIps+ --- \textit{This target is deprecated and will be ignored}. \item \verb+default_type = MimeType+ --- Defines the default MIME type to be used where \Yaws\ cannot determine it by its MIME types mappings. Default is \textit{text/plain}. \item \verb+default_charset = Charset+ --- Defines the default charset to be added when a response content-type is \textit{text/*}. By default, no charset is added. \item \verb+mime_types_file = File+ --- Overloads the default \textit{mime.types} file included with \Yaws{}. This file must use the following format: \begin{verbatim} # Lines beginning with a '#' or a whitespace are ignored # blank lines are also ignored \end{verbatim} The default file is located at \textit{\${PREFIX}/lib/yaws/priv/mime.types}. You should not edit this file because it may be replaced when you upgrade your server. \item \verb+add_types = ListOfTypes+ --- Specifies one or more mappings between MIME types and file extensions. More than one extension can be assigned to a MIME type. \textit{ListOfTypes} is defined as follows: \begin{verbatim} add_types = ... \end{verbatim} The mappings defined using this directive will overload all other definitions. If a file extension is defined several times, only the last one is kept. Multiple \textit{add\_types} directives may be used. \item \verb+add_charsets = ListOfCharsets+ --- Specifies one or more mappings between charsets and file extensions. More than one extension can be assigned to a charset. \textit{ListOfCharsets} is defined as follows: \begin{verbatim} add_charsets = ... \end{verbatim} The mappings defined using this directive will overload all other definitions. If a file extension is defined several times, only the last one is kept. Multiple \textit{add\_charsets} directives may be used. \end{itemize} \section{Server Part} \Yaws\ can virthost several web servers on the same IP address as well as several web servers on different IP addresses. The only limitation here is that there can be only one server with SSL enabled per each individual IP address. Each virtual host is defined within a matching pair of \verb++ and \verb++. The \verb+ServerName+ will be the name of the web server. The following directives are allowed inside a server definition. \begin{itemize} \item \verb+port = Port+ --- This makes the server listen on Port. Default is 8000. \item \verb+listen = IpAddress+ --- This makes the server listen on \verb+IpAddress+ when virthosting several servers on the same IP/port address, if the browser doesn't send a \verb+Host:+ field, \Yaws\ will pick the first server specified in the config file. Multiple \verb+listen+ directives may be used to specify several addresses to listen on. The default listen interface is 127.0.0.1. \item \verb+listen_backlog = Integer+ --- This sets the TCP listen backlog for the server to define the maximum length the queue of pending connections may grow to. The default is 1024. \item \verb+ .... + --- Defines extra options to be set on the listen socket and, by inheritance, on accepted sockets. See \verb+inet:setopts/2+ for details. Supported options are: \begin{itemize} \item \verb+Bbuffer = Integer+ (default: same as \verb+inet:setopts/2+) \item \verb+delay_send = true | false+ (default: same as \verb+inet:setopts/2+) \item \verb+linger = Integer | false+ (default: same as \verb+inet:setopts/2+) \item \verb+nodelay = true | false+ (default: same as \verb+inet:setopts/2+) \item \verb+priority = Integer+ (default: same as \verb+inet:setopts/2+) \item \verb+sndbuf = Integer+ (default: same as \verb+inet:setopts/2+) \item \verb+recbuf = Integer+ (default: same as \verb+inet:setopts/2+) \item \verb+send_timeout = Integer | infinity+ (default: same as \verb+inet:setopts/2+) \item \verb+send_timeout_close = true | false+ (default: same as \verb+inet:setopts/2+) \end{itemize} \item \verb+server_signature = String+ --- This directive sets the "Server: " output header to the custom value and overloads the global one for this virtual server. \item \verb+subconfig = File+ --- Same as \verb+subconfig+ directive of the global part, but here files should only contain directives allowed in the server part. \item \verb+subconfigdir = Directory+ --- Same as \verb+subconfigdir+ directive of the global part, but here files should only contain directives allowed in the server part. \item \verb+rhost = Host[:Port]+ --- This forces all local redirects issued by the server to go to Host. This is useful when \Yaws\ listens to a port which is different from the port that the user connects to. For example, running \Yaws\ as a non-privileged user makes it impossible to listen to port 80, since that port can only be opened by a privileged user. Instead \Yaws\ listens to a high port number port, 8000, and iptables are used to redirect traffic to port 80 to port 8000 (most NAT:ing firewalls will also do this for you). \item \verb+rmethod = http | https+ --- This forces all local redirects issued by the server to use this method. This is useful when an SSL off-loader, or stunnel, is used in front of \Yaws{}. \item \verb+auth_log = true | false+ --- Enable or disable the auth log for this virtual server. Default is true. \item \verb+access_log = true | false+ --- Setting this directive to false turns off traffic logging for this virtual server. The default value is true. \item \verb+logger_mod = Module+ --- It is possible to set a special module that handles access and auth logging. The default is to log all web server traffic to \verb+.access+ and \verb+.auth+ files in the configured or default \verb+logdir+. This module must implement the behaviour \verb+yaws_logger+. Default value is \verb+yaws_log+. The following functions should be exported: \begin{itemize} \item \verb+Module:open_log(ServerName, Type, LogDir)+ --- When \Yaws\ is started, this function is called for this virtual server. If the initialization is successful, the function must return \verb+{true, State}+ and if an error occurred, it must return \verb+false+. \item \verb+Module:close_log(ServerName, Type, State)+ -- This function is called for this virtual server when \Yaws\ is stopped. \item \verb+Module:wrap_log(ServerName, Type, State, LogWrapSize)+ --- This function is used to rotate log files. It is regularly called by \Yaws\ and must return the possibly updated internal \verb+NewState+. \item \verb+Module:write_log(ServerName, Type, State, Infos)+ -- When it needs to log a message, \Yaws\ will call this function. The parameter \verb+Infos+ is \verb+{Ip, Req, InHdrs, OutHdrs, Time}+ for an access log and \verb+{Ip, Path, Item}+ for an auth log, where: \begin{itemize} \item \verb+Ip+ --- IP address of the accessing client (as a tuple). \item \verb+Req+ --- The HTTP method, URI path, and HTTP version of the request (as an\\ \verb+#http_request{}+ record). \item \verb+InHdrs+ --- The HTTP headers which were sent from the WWW client (as a \verb+#headers{}+ record). \item \verb+OutHdrs+ --- The HTTP headers sent to the WWW client (as a \verb+#outh{}+ record). \item \verb+Path+ --- The URI path of the request (as a string). \item \verb+Item+ -- The result of an authentication request. May be \verb+{ok, User}+, \verb+403+ or\\ \verb+{401, Realm}+. \item \verb+Time+ --- The time taken to serve the request, in microseconds. \end{itemize} For all of these callbacks, \verb+ServerName+ is the virtual server's name, \verb+Type+ is the atom \verb+access+ or \verb+auth+ and \verb+State+ is the internal state of the logger. \end{itemize} \item \verb+shaper = Module+ --- Defines a module to control access to this virtual server. Access can be controlled based on the IP address of the client. It is also possible to throttle HTTP requests based on the client's download rate. This module must implement the behaviour \verb+yaws_shaper+. There is no such module configured by default. \item \verb+dir_listings = true | true_nozip | false+ --- Setting this directive to false disallows the automatic dir listing feature of \Yaws{}. A status code 403 Forbidden will be sent. Set to true\_nozip to avoid the auto-generated all.zip entries. Default is false. \item \verb+extra_cgi_vars = .....+ --- Add additional CGI or FastCGI variables. For example: \begin{verbatim} var = val ... \end{verbatim} \item \verb+statistics = true | false+ --- Turns on/off statistics gathering for a virtual server. Default is false. \item \verb+fcgi_app_server = Host:Port+ --- The hostname and TCP port number of a FastCGI application server. To specify an IPv6 address, put it inside square brackets (ex: "[::1]:9000"). The TCP port number is not optional. There is no default value. \item \verb+fcgi_trace_protocol = true | false+ --- Enable or disable tracing of FastCGI protocol messages as info log messages. Disabled by default. \item \verb+fcgi_log_app_error = true | false+ --- Enable or disable logging of application error messages (output to stderr and non-zero exit value). Disabled by default. \item \verb+deflate = true | false+ --- Turns on or off deflate compression for a server. Default is false. \item \verb+ ... + --- This begins and ends the deflate compression configuration for this server. The following items are allowed within a matching pair of and delimiters. \begin{itemize} \item \verb+min_compress_size = nolimit | Integer+ --- Defines the smallest response size that will be compressed. If nolimit is not used, the specified value must be strictly positive. The default value is nolimit. \item \verb+compress_level = none | default | best_compression | best_speed | 0..9+ ---\\ Defines the compression level to be used. 0 (none), gives no compression at all, 1 (best\_speed) gives best speed and 9 (best\_compression) gives best compression. The default value is default. \item \verb+window_size = 9..15+ --- Specifies the zlib compression window size. It should be in the range 9 through 15. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15. \item \verb+mem_level = 1..9+ --- Specifies how much memory should be allocated for the internal compression state. \verb+mem_level=1+ uses minimum memory but is slow and reduces compression ratio; \verb+mem_level=9+ uses maximum memory for optimal speed. The default value is 8. \item \verb+strategy = default | filtered | huffman_only+ --- This parameter is used to tune the compression algorithm. See \verb+zlib(3erl)+ for more details on the \verb+strategy+ parameter. The default value is default. \item \verb+use_gzip_static = true | false+ --- If true, \Yaws\ will try to serve precompressed versions of static files. It will look for precompressed files in the same location as original files that end in ".gz". Only files that do not fit in the cache are concerned. The default value is false. \item \verb+mime_types = ListOfTypes | defaults | all+ --- Restricts the deflate compression to particular MIME types. The special value all enable it for all types (It is a synonym of `*/*'). MIME types into \verb+ListOfTypes+ must have the form `type/subtype' or `type/*' (indicating all subtypes of that type). Here is an example: \begin{verbatim} mime_types = default image/* mime_types = application/xml application/xhtml+xml application/rss+xml \end{verbatim} By default, the following MIME types are compressed (if \verb+deflate+ is set to true): \begin{itemize} \item \verb+text/*+ \item \verb+application/rtf+ \item \verb+application/msword+ \item \verb+application/pdf+ \item \verb+application/x-dvi+ \item \verb+application/javascript+ \item \verb+application/x-javascript+ \end{itemize} Multiple \verb+mime_types+ directive can be used. \end{itemize} \item \verb+docroot = Directory ...+ --- This makes the server serve all its content from \verb+Directory+. It is possible to pass a space-separated list of directories as docroot. If this is the case, the various directories will be searched in order for the requested file. This also works with the ssi and yssi constructs where the full list of directories will be searched for files to ssi/yssi include. Multiple docroot directives can be used. You need at least one valid docroot, other invalid docroots are skipped with their associated auth structures. \item \verb+auth_skip_docroot = true | false+ --- If true, the docroot will not be searched for \verb+.yaws_auth+ files. This is useful when the docroot is quite large and the time to search it is prohibitive when \Yaws\ starts up. Defaults to false. \item \verb+partial_post_size = Integer+ --- When a \Yaws\ file receives large \verb+POST+s, the amount of data received in each chunk is determined by this parameter. The default value is 10240. Setting it to nolimit is potentially dangerous. \item \verb+dav = true | false+ --- Turns on the WebDAV protocol for this server. The WebDAV support adds class 1, 2 and 3 compliancy which includes: \begin{itemize} \item XML request body parsing and multistatus responses \item PROPFIND and PROPPATCH methods returning properties asked for \item all RFC4918 properties, the Apache executable property plus some Microsoft extensions \item locking mechanism (class 2 compliancy) on all destructive methods \item If header parsing \item Passes most litmus tests, except those concerning unknown properties \end{itemize} If WebDAV is turned on, processing of \verb+.yaws+ pages is turned off. Default is false. The \verb+dav=true+ configuration option is short for: \begin{verbatim} runmod = yaws_runmod_lock ... ... appmods = \end{verbatim} \item \verb+tilde_expand = true|false+ --- If this value is set to false \Yaws\ will never do tilde expansion. Tilde expansion takes a URL of the form \verb+http://www.foo.com/+\char`\~\verb+username+ and changes it into a request where the docroot for that particular request is set to the directory \char`\~\verb+username/public_html/+. The default value is false. \item \verb+allowed_scripts = ListOfSuffixes+ --- The allowed script types for this server. Recognized are \textit{yaws}, \textit{cgi}, \textit{fcgi}, \textit{php}. Default is \verb+allowed_scripts = yaws php cgi fcgi+. \item \verb+tilde_allowed_scripts = ListOfSuffixes+ --- The allowed script types for this server when executing files in a users \verb+public_html+ folder Recognized are \textit{yaws}, \textit{cgi}, \textit{fcgi}, \textit{php}. Default is\\ \verb+tilde_allowed_scripts =+ (i.e., empty). \item \verb+index_files = ListOfResources+ --- This directive sets the list of resources to look for, when a directory is requested by the client. If the last entry begins with a `/', and none of the earlier resources are found, \Yaws\ will perform a redirect to this uri.\\ Default is \verb+index_files = index.yaws index.html index.php+. \item \verb+appmods = ListOfModuleNames+ --- If any of the names in \verb+ListOfModuleNames+ appear as components in the path for a request, the path request parsing will terminate and that module will be called. There is also an alternate syntax for specifying the appmods if we don't want our internal erlang module names to be exposed in the URL paths. We can specify \begin{verbatim} appmods = ... \end{verbatim} Assume for example that we have the URL \url{http://www.hyber.org/myapp/foo/bar?user=joe} while we have the module \verb+foo+ defined as an appmod, the function \verb+foo:out(Arg)+ will be invoked instead of searching the filesystems below the point \verb+foo+. The \verb+Arg+ argument will have the missing path part supplied in its \verb+appmoddata+ field. It is also possible to exclude certain directories from appmod processing. This is particulaly interesting for '/' appmods. Here is an example: \begin{verbatim} appmods = \end{verbatim} The above configuration will invoke the \verb+myapp+ erlang module on everything except any file found in directories \verb+icons+, \verb+js+ and \verb+top/static+ relative to the docroot. \item \verb+dispatchmod = DispatchModule+ --- Set \verb+DispatchModule+ as a server-specific request dispatching module. \Yaws\ expects \verb+DispatchModule+ to export a \verb+dispatch/1+ function. When it receives a request, \Yaws\ passes an \verb+#arg{}+ record to the dispatch module's \verb+dispatch/1+ function, which returns one of the following atom results: \begin{itemize} \item \verb+done+ --- this indicates the dispatch module handled the request itself and already sent the response, and \Yaws\ should resume watching for new requests on the connection \item \verb+closed+ --- same as \verb+done+ but the \verb+DispatchModule+ also closed the connection \item \verb+continue+ --- the dispatch module has decided not to handle the request, and instead wants \Yaws\ to perform its regular request dispatching \end{itemize} Note that when \verb+DispatchModule+ handles a request itself, \Yaws\ does not support tracing, increment statistics counters or allow traffic shaping for that request. It does however still keep track of maximum keepalive uses on the connection. \item \verb+errormod_404 = Module+ --- It is possible to set a special module that handles 404 Not Found messages. The function\\ \verb+Module:out404(Arg, GC, SC)+ will be invoked. The arguments are \begin{itemize} \item \verb+Arg+ --- a \verb+#arg{}+ record \item \verb+GC+ --- a \verb+#gconf{}+ record (defined in yaws.hrl) \item \verb+SC+ --- a \verb+#sconf{}+ record (defined in yaws.hrl) \end{itemize} The function can and must do the same things that a normal \verb+out/1+ does. \item \verb+errormod_401 = Module+ --- It is possible to set a special module that handles 401 Unauthorized messages. This can for example be used to display a login page instead. The function \\ \verb+Module:out401(Arg, Auth, Realm)+ will be invoked. The arguments are \begin{itemize} \item \verb+Arg+ --- a \verb+#arg{}+ record \item \verb+Auth+ --- a \verb+#auth{}+ record \item \verb+Realm+ --- a string \end{itemize} The function can and must do the same things that a normal \verb+out/1+ does. \item \verb+errormod_crash = Module+ --- It is possible to set a special module that handles the HTML generation of server crash messages. The default is to display the entire formatted crash message in the browser. This is good for debugging but not in production. The function \verb+Module:crashmsg(Arg, SC, Str)+ will be called. The \verb+Str+ is the real crash message formatted as a string. The function must return, \verb+{content,MimeType,Cont}+ or \verb+{html, Str}+ or \verb+{ehtml, Term}+. That data will be shipped to the client. \item \verb+expires = ListOfExpires+ --- Controls the setting of the \verb+Expires+ HTTP header and the \verb+max-age+ directive of the \verb+Cache-Control+ HTTP header in server responses for specific MIME types. The expiration date can set to be relative to either the time the source file was last modified, or to the time of the client access. \verb+ListOfExpires+ is defined as follows: \begin{verbatim} expires = ... \end{verbatim} These HTTP headers are an instruction to the client about the document's validity and persistence. If cached, the document may be fetched from the cache rather than from the source until this time has passed. After that, the cache copy is considered "expired" and invalid, and a new copy must be obtained from the source. Here is an example: \begin{verbatim} expires = expires = \end{verbatim} \item \verb+arg_rewrite_mod = Module+ --- It is possible to install a module that rewrites all the \verb+Arg+ \verb+#arg{}+ records at an early stage in the \Yaws\ server. This can be used to do various things such as checking a cookie, rewriting paths etc. An \verb+arg_rewrite_mod+ must export an \verb+arg_rewrite/1+ function taking and returning an \verb+#arg{}+ record. If the function wants to return a response, it must set the \verb+#arg.state+ field of its return value to an instance of the \verb+#rewrite_response{}+ record. The module \verb+yaws_vdir+ can be used in case you want to serve static content that is not located in your docroot. See the example at the bottom of this man page for how to use the \verb+opaque+ + \verb+vdir+ elements to instruct the \verb+yaws_vdir+ module what paths to rewrite. \item \verb+start_mod = Module+ --- Defines a user-provided callback module. At startup of the server,\\ \verb+Module:start/1+ will be called. The \verb+#sconf{}+ record (defined in \verb+yaws.hrl+) will be used as the input argument. This makes it possible for a user application to synchronize the startup with the \Yaws\ server as well as getting hold of user specific configuration data, see the explanation for the \verb++ context. \item \verb+revproxy = Prefix Url [intercept_mod Module]+ --- Make \Yaws\ a reverse proxy. \verb+Prefix+ is a path inside our own docroot and \verb+Url+ is a URL pointing to a website we want to "mount" under the \verb+Prefix+ path. For example: \verb+revproxy = /tmp/foo http://yaws.hyber.org+ This makes the hyber website appear under \verb+/tmp/foo+. It is possible to have multiple reverse proxies inside the same server by supplying multiple \verb+revproxy+ directives. If the optional keyword \verb+intercept_mod+ and \verb+Module+ are supplied in the \verb+revproxy+ directive, then \verb+Module+ indicates a proxy request and response interception module. When the reverse proxy receives a request from a client, it will first pass \verb+#http_request{}+ and \verb+#headers{}+ records representing the client request to the intercept module's \verb+rewrite_request/2+ function. The function must return a 3-tuple of the following form: \begin{verbatim} {ok, #http_request{}, #headers{}} \end{verbatim} where the record instances can be the original values passed in or new values. The reverse proxy will use these record instances when passing the request to the backend server. Similarly, when the backend server returns a response, the reverse proxy will call the intercept module's \verb+rewrite_response/2+ function, passing it an \verb+#http_response{}+ record and a \verb+#headers{}+ record. The function must return a 3-tuple of the following form: \begin{verbatim} {ok, #http_response{}, #headers{}} \end{verbatim} where the record instances can be the original values passed in or new values. The reverse proxy will use these record instances when returning the response to the client. Any failure within an intercept module function results in HTTP status code 500 (Internal Server Error) being returned to the client. Intercept modules can use the following functions from the \verb+yaws_api+ module to retrieve, set, or delete HTTP headers from \verb+#headers{}+ records: \begin{itemize} \item \verb+set_header/2+, \verb+set_header/3+ \item \verb+get_header/2+, \verb+get_header/3+ \item \verb+merge_header/2+, \verb+merge_header/3+ \item \verb+delete_header/2+ \end{itemize} \item \verb+fwdproxy = true|false+ --- Make \Yaws\ a forward proxy. By enabling this option you can use \Yaws\ as a proxy for outgoing web traffic, typically by configuring the proxy settings in a web-browser to explicitly target \Yaws\ as its proxy server. \item \verb+servername = Name+ --- If we're virthosting several servers and want to force a server to match specific \verb+Host:+ headers we can do this with the \verb+servername+ directive. This name doesn't necessarily have to be the same as the name inside \verb++ in certain NAT scenarios. Rarely used feature. \item \verb+serveralias = ListOfNames+ --- This directive sets the alternate names for a virtual host. A server alias may contain wildcards: \begin{itemize} \item '*' matches any sequence of zero or more characters \item '?' matches one character unless that character is a period ('.') \end{itemize} Multiple \verb+serveralias+ directives may be used. Here is an example: \begin{verbatim} serveralias = server server2.domain.com server2 serveralias = *.server.domain.com *.server?.domain.com ... \end{verbatim} \item \verb+php_handler+ --- Set handler to interpret \textit{.php} files. It can be one of the following definitions: \begin{itemize} \item \verb+php_handler = + --- The name of (and possibly path to) the PHP executable used to interpret PHP scripts (if allowed). \item \verb+php_handler = + --- Use the specified FastCGI server to interpret \textit{.php} files (if allowed). \Yaws\ does not start the PHP interpreter in FastCGI mode for you. To run PHP in FastCGI mode, call it with the \textit{-b} option. For example: \begin{verbatim} php5-cgi -b '127.0.0.1:54321' \end{verbatim} This starts PHP5 in FastCGI mode listening on the local network interface. To make use of this PHP server from \Yaws{}, specify: \begin{verbatim} php_handler = \end{verbatim} If you need to specify an IPv6 address, use square brackets: \begin{verbatim} php_handler = \end{verbatim} The PHP interpreter needs read access to the files it is to serve. Thus, if you run it in a different security context than \Yaws\ itself, make sure it has access to the \textit{.php} files. Please note that anyone who is able to connect to the PHP FastCGI server directly can use it to read any file to which it has read access. You should consider this when setting up a system with several mutually untrusted instances of PHP. \item \verb+php_handler = + --- Use an external handler, possibly on another node, to interpret \textit{.php} files (if allowed). To interpret a \textit{.php} file, the function \verb+Module:Function(Arg)+ will be invoked (evaluated inside an rpc call if a \verb+Node+ is specified), where \verb+Arg+ is an \verb+#arg{}+ record. The function must do the same things that a normal \verb+out/1+ does. \end{itemize} Default value is \verb++. \item \verb+phpfcgi = HostPortSpec+ --- \textit{this target is deprecated. use php\_handler target in server part instead}. Using this directive is the same as: \verb+php_handler = +. \item \verb+default_type = MimeType+ --- Overloads the global \verb+default_type+ value for this virtual server. \item \verb+default_charset = Charset+ --- Overloads the global \verb+default_charset+ value for this virtual server. \item \verb+mime_types_file = File+ --- Overrides the global \verb+mime_type_file+ value for this virtual server. Mappings defined in \textit{File} will not overload those defined by \verb+add_types+ directives in the global part. \item \verb+add_types = ListOfTypes+ --- Overloads the global \verb+add_types+ values for this virtual server. If a mapping is defined in the global part and redefined in a server part using this directive, then it is replaced. Else it is kept. \item \verb+add_charsets = ListOfCharsets+ --- Overloads the global \verb+add_charsets+ values for this virtual server. If a mapping is defined in the global part and redefined in a server part using this directive, then it is replaced. Else it is kept. \item \verb+nslookup_pref = [inet | inet6]+ --- For fcgi servers and revproxy URLs, define the name resolution preference. For example, to perform only IPv4 name resolution, use \textit{[inet]}. To do both IPv4 and IPv6 but try IPv6 first, use \textit{[inet6, inet]}. Default value is \textit{[inet]}. \item \verb+ .... + This begins and ends an SSL configuration for this server. It's possible to virthost several SSL servers on the same IP given that they all share the same certificate configuration. In general it is complicated to virthost several SSL servers on the same IP address since the certificate is typically bound to a domainname in the common name part of the certificate. One solution (the only?) to this problem is to have a certificate with multiple subjectAltNames. See \url{http://wiki.cacert.org/VhostTaskForce#Interoperability_Test} \begin{itemize} \item \verb+keyfile = File+ --- Specifies which file contains the private key for the certificate. \item \verb+certfile = File+ --- Specifies which file contains the certificate for the server. \item \verb+cacertfile = File+ --- A file containing trusted certificates to use during client authentication and to use when attempting to build the server certificate chain. The list is also used in the list of acceptable client CAs passed to the client when a certificate is requested. \item \verb+dhfile = File+ --- A file containing PEM-encoded Diffie-Hellman parameters to be used by the server if a cipher suite using Diffie-Hellman key exchange is negotiated. If not specified, default parameters are used. \item \verb+verify = 0 | 1 | 2 | verify_none | verify_peer+ --- Specifies the level of verification the server does on client certs. 0 means that the server will not ask for a cert (\verb+verify_none+), 1 means that the server will ask the client for a cert but not fail if the client does not supply a client cert (\verb+verify_peer+, \verb+fail_if_no_peer_cert+ = \verb+false+), 2 means that the server requires the client to supply a client cert (\verb+verify_peer+, \verb+fail_if_no_peer_cert+ = \verb+true+). Setting \verb+verify_none+ means that the x509 validation will be skipped (no certificate request is sent to the client), \verb+verify_peer+ means that a certificate request is sent to the client (x509 validation is performed. You might want to use \verb+fail_if_no_peer_cert+ in combination with \verb+verify_peer+. \item \verb+fail_if_no_peer_cert = true | false+ --- If verify is set to \verb+verify_peer+ and set to \verb+true+ the connection will fail if the client does not send a certificate (i.e. an empty certificate). If set to false the server will fail only if an invalid certificate is supplied (an empty certificate is considered valid). \item \verb+depth = Int+ --- Specifies the depth of certificate chains the server is prepared to follow when verifying client certs. For the OTP new SSL implementation it is also used to specify how far the server, i.e. we, shall follow the SSL certificates we present to the clients. Hence, using self signed certs, we typically need to set this to 0. \item \verb+password = String+ --- If the private key is encrypted on disk, this password is the 3des key to decrypt it. \item \verb+ciphers = String+ --- This string specifies the SSL cipher string. The syntax of the SSL cipher string is a little horrible sub-language of its own. It is documented in the SSL man page for "ciphers". \item \verb+secure_renegotiate = true | false+ --- Specifies whether to reject renegotiation attempt that does not live up to RFC 5746. By default \verb+secure_renegotiate+ is set to false i.e. secure renegotiation will be used if possible but it will fallback to unsecure renegotiation if the peer does not support RFC 5746. \item \verb+client_renegotiation = true | false+ --- Enables or disables the Erlang/OTP SSL application client renegotiation option. Defaults to true. See the \verb+ssl+ manual page at http://www.erlang.org/doc/man/ssl.html for more details. \textbf{WARNING: This option was introduced in the SSL application in Erlang/OTP 18.0, so \Yaws\ ignores it for previous releases.} \item \verb+honor_cipher_order = true | false+ --- If true (the default), use the server's preference for cipher selection. If false, use the client's preference. \textbf{WARNING: This option was introduced in the SSL application in Erlang/OTP 17.0, so \Yaws\ ignores it for previous releases.} \item \verb+protocol_version = ProtocolList+ --- Specifies the list of SSL protocols that will be supported. If not set, defaults to all protocols supported by the \Erlang\ \verb+ssl+ application. For example, to support only TLS versions 1.2, 1.1, and 1: \begin{verbatim} protocol_version = tlsv1.2, tlsv1.1, tlsv1 \end{verbatim} \textbf{WARNING: Because of a bug in previous releases, Erlang/OTP R16B01 or newer is required for this to work.} \end{itemize} \item \verb+ ... + --- Defines a redirect mapping. The following items are allowed within a matching pair of \verb++ and \verb++ delimiters. We can have a series of redirect rules in one of the formats below: \begin{verbatim} Path = URL Path = code Path = code URL \end{verbatim} \verb+Path+ must be an url-decoded path beginning with a slash. \verb+URL+ may be either a relative URL (a path beginning with a slash), or an absolute URL. In the first case, the \textit{scheme:hostname:port} of the current server will be added. All accesses to \verb+Path+ will be redirected to \verb+URL/Path+ (or \\ \verb+scheme:hostname:port/URL/Path+ if \verb+URL+ is relative). \verb+URL+ must be url-encoded. Note that the original path is appended to the redirected URL. For example, assume we have the following redirect configuration: \begin{verbatim} /foo = http://www.mysite.org/zapp /bar = /tomato.html \end{verbatim} Assuming this config resides on a site called \url{http://abc.com}, we have the following redirects: \begin{verbatim} http://abc.com/foo -> http://www.mysite.org/zapp/foo http://abc.com/foo/test -> http://www.mysite.org/zapp/foo/test http://abc.com/bar -> http://abc.com/tomato.html/bar http://abc.com/bar/x/y/z -> http://abc.com/tomato.html/bar/x/y/z \end{verbatim} By default, \Yaws\ will perform a 302 redirect. The HTTP status code can be changed using the \verb+code+ parameter. Note that \Yaws\ must have knowledge of the status code value. \begin{itemize} \item For 3xx status codes, the \verb+URL+ parameter must be present and will be used to build the new location. \item For other status codes (1xx, 2xx, 4xx and 5xx), the \verb+URL+ can be omitted. In the absence of \verb+URL+, \Yaws\ will return a generic response with the specified status code. \item Otherwise, the \verb+URL+ parameter must be a relative URL and will be used to customize the response. \end{itemize} Sometimes we do not want to have the original path appended to the redirected path. To get that behaviour we specify the config with '==' instead of '='. \begin{verbatim} /foo == http://www.mysite.org/zapp /bar = /tomato.html \end{verbatim} With this configuration, a request for \url{http://abc.com/foo/x/y/z} simply gets redirected to \\ \url{http://www.mysite.org/zapp}. This is typically used when we simply want a static redirect at some place in the docroot. When we specify a relative URL as the target for the redirect, the redirect will be to the current http(s) server. \item \verb+ ... + --- Defines an auth structure. The following items are allowed within a matching pair of and delimiters. \begin{itemize} \item \verb+docroot = Docroot+ --- If a \verb+Docroot+ is defined, this auth structure will be tested only for requests in the specified docroot. No docroot configured means all docroots. If two auth structures are defined, one with a docroot and one with no docroot, the first of both overrides the second one for requests in the configured docroot. \item \verb+dir = Dir+ --- Makes \verb+Dir+ to be controlled by WWW\-authenticate headers. In order for a user to have access to WWW\-Authenticate controlled directory, the user must supply a password. The \verb+Dir+ must be specified relative to the docroot. Multiple dir can be used. If no dir is set, the default value, "/", will be used. \item \verb+realm = Realm+ --- In the directory defined here, the WWW-Authenticate Realm is set to this value. \item \verb+authmod = AuthMod+ --- If an \verb+AuthMod+ is defined then \verb+AuthMod:auth(Arg, Auth)+ will be called for all access to the directory. The \verb+auth/2+ function should return one of: \verb+true+, \verb+false+, \verb+{false, Realm}+, \verb+{appmod, Mod}+. If \verb+{appmod, Mod}+ is returned then a call to\\ \verb+Mod:out401(Arg, Auth, Realm)+ will be used to deliver the content. If \verb+errormod_401+ is defined, the call to \verb+Mod+ will be ignored. (\verb+Mod:out(Arg)+ is deprecated). This can, for example, be used to implement cookie authentication. The \verb+auth()+ callback would check if a valid cookie header is present, if not it would return \verb+{appmod, ?MODULE}+ and the \verb+out401/1+ function in the same module would return \verb+{redirect_local, "/login.html"}+. \item \verb+user = User:Password+ --- Inside this directory, the user \verb+User+ has access if the user supplies the password \verb+Password+ in the popup dialogue presented by the browser. We can obviously have several of these value inside a single pair. The usage of User:Password in the actual config file is deprecated as of release 1.51. It is preferred to have the users in a file called \verb+.yaws_auth+ in the actual directory. The \verb+.yaws_auth+ file has to be parseable by \verb+file:consult/1+. Each row of the file must contain terms in this form: \begin{verbatim} {User, Password}. \end{verbatim} where both \verb+User+ and \verb+Password+ should be strings. The \verb+.yaws_auth+ file mechanism is recursive,so any subdirectories of \verb+Dir+ are also automatically protected. The \verb+.yaws_auth+ file is never visible in a dir listing. \item \verb+pam service = pam-service+ --- If the item \verb+pam+ is part of the auth structure, Yaws will also try to authenticate the user using "pam" using the pam \verb+service+ indicated. Usual services are typically found under /etc/pam.d. Usual values are "system-auth" etc. pam authentication is performed by an Erlang port program which is typically installed as suid root by the Yaws install script. \item \verb+allow = all | ListOfHost+ --- The \verb+allow+ directive affects which hosts can access an area of the server. Access can be controlled by IP address or IP address range. If all is specified, then all hosts are allowed access, subject to the configuration of the \verb+deny+ and \verb+order+ directives. To allow only particular hosts or groups of hosts to access the server, the host can be specified in any of the following formats: A full IP address \begin{verbatim} allow = 10.1.2.3 allow = 192.168.1.104, 192.168.1.205 \end{verbatim} network/netmask pair \begin{verbatim} allow = 10.1.0.0/255.255.0.0 \end{verbatim} network/nnn CIDR specification \begin{verbatim} allow = 10.1.0.0/16 \end{verbatim} \item \verb+deny = all | ListOfHost+ --- This directive allows access to the server to be restricted based on IP address. The arguments for the \verb+deny+ directive are identical to the arguments for the \verb+allow+ directive. \item \verb+order = Ordering+ --- The \verb+order+ directive, along with \verb+allow+ and \verb+deny+ directives, controls a three-pass access control system. The first pass processes either all \verb+allow+ or all \verb+deny+ directives, as specified by the \verb+order+ directive. The second pass parses the rest of the directives (\verb+deny+ or \verb+allow+). The third pass applies to all requests which do not match either of the first two. Ordering is one of (Default value is \verb+deny,allow+): \begin{itemize} \item \verb+allow,deny+ --- First, all \verb+allow+ directives are evaluated; at least one must match, or the request is rejected. Next, \verb+deny+ directives are evaluated. If any matches, the request is rejected. Last, any requests which do not match an \verb+allow+ or a \verb+deny+ directive are denied by default. \item \verb+deny,allaw+ --- First, all \verb+deny+ directives are evaluated; if any matches, the request is denied unless it also matches an \verb+allow+ directive. Any requests which do not match any \verb+allow+ or \verb+deny+ directives are permitted. \end{itemize} \end{itemize} \item \verb+ ... + --- This begins and ends an opaque configuration context for this server, where '\verb+Key = Value+' directives can be specified. These directives are ignored by \Yaws\ (hence the name opaque), but can be accessed as a list of tuples \verb+{Key,Value}+ stored in the \verb+#sconf.opaque+ record entry. See also the description of the \verb+start_mod+ directive. This mechanism can be used to pass data from a surrounding application into the individual .yaws pages. \end{itemize} \section{Configuration Examples} The following example defines a single server on port 80. \begin{verbatim} logdir = /var/log/yaws port = 80 listen = 192.168.128.31 docroot = /var/yaws/www \end{verbatim} And this example shows a similar setup but two web servers on the same IP address: \begin{verbatim} logdir = /var/log/yaws port = 80 listen = 192.168.128.31 docroot = /var/yaws/www port = 80 listen = 192.168.128.31 docroot = /var/yaws/www_funky_org \end{verbatim} When there are several virtual hosts defined for the same IP number and port, and an HTTP request arrives with a \verb+Host+ field that does not match any defined virtual host, then the one which defined ``first'' in the file is chosen. An example with www-authenticate and no access logging at all. \begin{verbatim} logdir = /var/log/yaws port = 80 listen = 192.168.128.31 docroot = /var/yaws/www access_log = false dir = /var/yaws/www/secret realm = foobar user = jonny:verysecretpwd user = benny:thequestion user = ronny:havinganamethatendswithy \end{verbatim} And finally a slightly more complex example with two servers on the same IP, and one SSL server on a different IP. The \verb+is_default+ is used to select the funky server if someone types in for example url{http://192.168.128.31/} in his\slash her browser. \begin{verbatim} logdir = /var/log/yaws max_num_cached_files = 8000 max_num_cached_bytes = 6000000 port = 80 listen = 192.168.128.31 docroot = /var/yaws/www port = 80 is_default = true listen = 192.168.128.31 docroot = /var/yaws/www_funky_org port = 443 listen = 192.168.128.32 docroot = /var/yaws/www_funky_org keyfile = /etc/funky.key certfile = /etc/funky.cert password = gazonk \end{verbatim} \chapter{WebSocket Protocol Support} \label{websockets} \Yaws\ supports the WebSocket Protocol (RFC 6455), which enables two-way communication between clients and web servers. \Yaws\ also provides support for working drafts of the WebSocket protocol, specifically drafts 10 to 17 of the hybi working group. No support for other drafts, such as those from the hixie working group, is provided. You can find example usage of the WebSocket Protocol in the file \verb+www/websockets_example.yaws+. This example, intended for use with any browser supporting RFC 6455, returns HTML and JavaScript that allow the client to establish a WebSocket connection to the server. These connections are handled by the code in \verb+www/websockets_example_endpoint.yaws+, which when invoked simply establishes \\ \verb+examples/src/basic_echo_callback.erl+ as the WebSocket callback module for the connection. \section{Establish a WebSocket connection} First of all, to establish a WebSocket connection, a client must send a valid HTTP Upgrade request. Then, from the server side, the \Yaws\ script (or the appmod or whatever) should return: \begin{verbatim} {websocket, CallbackMod, Options} \end{verbatim} where \verb+CallbackMod+ is an atom identifying the WebSocket callback module, and \verb+Options+ is a (possibly empty) list (see below for details). From here, \Yaws\ spawns an Erlang process to manage the WebSocket connection. Once the handshake response is returned by \Yaws, the connection is established and the handling process is ready to send or receive data. If something goes wrong during this step, \Yaws\ returns an HTTP error (400, 403 or 500 depending of the error type). \subsection{Supported options} The following options are available: \begin{itemize} \item \verb+{callback, CallbackType}+ --- Specify the type of the callback module. \verb+CallbackType+ can be either of the following: \begin{itemize} \item \verb+basic+ --- Same as \verb+{basic, []}+. This is the default. \item \verb+{basic, InitialState}+ --- Indicate your callback module is a basic callback module. \\ \verb+InitialState+ is the callback's initial state for handling this client. \item \verb+{advanced, InitialState}+ --- Same as above but for an advanced callback module. \end{itemize} \item \verb+{origin, Origin}+ --- Specify the \verb+Origin+ URL from which messages will be accepted. This is useful for protecting against cross-site attack. The option defaults to \verb+any+, meaning calls will be accepted from any origin. \item \verb+{keepalive, KeepAliveBoolean}+ --- If true, \Yaws\ will automatically send a ping message every \verb+keepAliveTimeout+ milliseconds. By default keepalive pings are disabled. \item \verb+{keepalive_timeout, keepAliveTimeout}+ --- Specify the interval in milliseconds to send \\ keepalive pings, by default 30000. Ignored if \verb+KeepAliveBoolean+ is false. \item \verb+{keepalive_grace_period, KeepAliveGracePeriod}+ --- Specify the amount of time, in milliseconds, to wait after sending a keepalive ping. If no message is received within \\ \verb+KeepAliveGracePeriod+ milliseconds, a timeout will occur. Depending on the \verb+DropBoolean+ value, a close frame is sent with the status code 1006 (if \verb+DropBoolean+ is true) or the callback module is notified (see \verb+Module:handle_info/2+ below). By default, \verb+KeepAliveGracePeriod+ is set to 2000. Ignored if \verb+KeepAliveBoolean+ is false. \item \verb+{drop_on_timeout, DropBoolean}+ --- If true, a close frame is sent with the status code 1006 when a timeout occurs after a keepalive ping has been sent (see \verb+KeepAliveGracePeriod+). Disabled by default. Ignored if \verb+KeepAliveBoolean+ is false. \item \verb+{close_timeout, CloseTimeout}+ --- After sending a close frame to a client, \Yaws\ will wait for the client acknowledgement for \verb+CloseTimeout+ milliseconds. Then it will close the underlying TCP connection. By default \verb+CloseTimeout+ is set to 5000. \item \verb+{close_if_unmasked, CloseUnmaskedBoolean}+ --- If true, \Yaws\ will reject any unmasked incoming frame by sending a close frame with the status code 1002. Disabled by default. Note: According to RFC 6455, a client must mask all frames that it sends to the server (see RFC 6455 section 5.1). \item \verb+{max_frame_size, MaxFrameSize}+ --- Specify the maximum allowed size, in bytes, for received frames. By default 16MB. It is also the maximum size for unfragmented messages. This limit is checked for all types of callback module. \item \verb+{max_message_size, MaxMsgSize}+ --- Specify the maximum allowed message size in bytes, by default 16MB. This limit is checked only for basic callback modules. \item \verb+{auto_fragment_message, AutoFragBoolean}+ --- If true, outgoing messages will be automatically fragmented if their payload exceeds \verb+OutFragSize+ bytes. This flag is set to false by default. \item \verb+{auto_fragment_threshold, OutFragSize}+ --- Specify the maximum payload size of each fragment if \verb+AutoFragBoolean+ is true. \verb+OutFragSize+ is set to 1MB by default. This setting is ignored if \verb+AutoFragBoolean+ is false. \end{itemize} \section{WebSocket Callback Modules} All frames received on a WebSocket connection are passed to the callback modules specified during the connection establishment by calling \verb+Module:handle_message/1+ or \verb+Module:handle_message/2+. depending on whether it's a basic or an advanced callback module. \subsection{Basic Callback Modules} \label{basic-callback-modules} When a basic callback module is used, the messages defragmentation is handled by \Yaws. From the callback module point of view, all incoming messages are unfragmented. This implies that fragmented frames will be accumulated, thus basic callback modules does not support data streaming. A basic callback module \textbf{MUST} define the stateless function \verb+Module:handle_message/1+: \begin{quote} \textbf{Module:handle\_message(Message) -> Result} \begin{verbatim} Message :: {Type, Data} | {close, Status, Reason} Result :: noreply | {reply, Reply} | {close, CloseReason} Type :: text | binary Data :: binary() Reply :: {Type, Data} | #ws_frame{} | [{Type, Data}] | [#ws_frame{}] CloseReason :: Status | {Status, Reason} Status :: integer() %% RFC 6455 Status Code Reason :: binary() \end{verbatim} This function is called when a message is received. \verb+{text, Data}+ (or \verb+{binary, Data}+) is the unfragmented text (or binary) message. When the client closes the connection, the callback module is notified with the message \verb+{close, Status, Reason}+, where \verb+Status+ is the numerical status code sent by the client or the value 1000 (see RFC 6455 section 7.4.1) if the client sent no status code. For an abnormal client closure, the status code is 1006 (as specified by RFC 6455 section 7.1.5). \verb+Reason+ is a binary containing any text the client sent to indicate the reason for closing the socket; this binary may be empty. If the function returns \verb+{reply, Reply}+, \verb+Reply+ is sent to the client. It is possible to send one or more unfragmented messages by returning \verb+{Type, Data}+ or \verb+[{Type, Data}]+. It is also possible to send one or more frames using the \verb+#ws_frame{}+ record instead, defined in \verb+include/yaws_api.hrl+ (useful to fragment messages by hand). If the function returns \verb+noreply+, nothing happens. If the function returns \verb+{close, CloseReason}+, the handling process closes the connection sending a close control frame to the client. \verb+CloseReason+ is used to set the status code and the (optional) close reason of the close control frame. Then the handling process terminates calling \verb+Module:terminate(CloseReason, State)+ (if defined, see below). \end{quote} Because just handling messages is not enough for real applications, a basic callback module can define optional functions, mainly to manage a callback state. It can define one, some or all of the following functions: \begin{quote} \textbf{Module:init(Args) -> Result} \begin{verbatim} Args :: [ReqArg, InitialState] Result :: {ok, State} | {ok, State, Timeout} | {error, Reason} ReqArg :: #arg{} InitialState :: term() State :: term() Timeout :: integer() >= 0 | infinity Reason :: term() \end{verbatim} If defined, this function is called to initialize the internal state of the callback module. \verb+ReqArg+ is the \verb+#arg{}+ record supplied to the \verb+out/1+ function and \verb+InitialState+ is the term associated to the \verb+CallbackType+ described above. If an integer timeout value is provided, it will overload the next keepalive timeout (see the \verb+keepalive_timeout+ option above). The atom \verb+infinity+ can be used to wait indefinitely. If no value is specified, the default keepalive timeout is used. If something goes wrong during initialization, the function should return \verb+{error, Reason}+, where \verb+Reason+ is any term. \end{quote} \begin{quote} \textbf{Module:handle\_open(WSState, State) -> Result} \begin{verbatim} WSState :: #ws_state{} State :: term() Result :: {ok, NewState} | {error, Reason} NewState :: term() Reason :: term() \end{verbatim} If defined, this function is called when the connection is upgraded from HTTP to WebSocket. \verb+WSState+ is the state of the WebSocket connection. It can be used to send messages to the client using \verb+yaws_api:websocket_send(WSState, Message)+. \verb+State+ is the internal state of the callback module. If the function returns \verb+{ok, NewState}+, the handling process will continue executing with the possibly updated internal state \verb+NewState+. If the function returns \verb+{error, Reason}+, the handling process closes the connection and terminates calling \verb+Module:terminate({error, Reason}, State)+ (if defined, see below). \end{quote} \begin{quote} \textbf{Module:handle\_message(Message, State) -> Result} \begin{verbatim} Message :: see Module:handle_message/1 State :: term() Result :: {noreply, NewState} | {noreply, NewState, Timeout} | {reply, Reply} | {reply, Reply, NewState} | {reply, Reply, NewState, Timeout} | {close, CloseReason, NewState} | {close, CloseReason, Reply, NewState} NewState :: term() Timeout :: integer() >= 0 | infinity Reply :: see Module:handle_message/1 CloseReason :: see Module:handle_message/1 \end{verbatim} If defined, this function is called in place of \verb+Module:handle_message/1+. The main difference with the previous version is that this one handles the internal state of the callback module. \verb+State+ is internal state of the callback module. See \verb+Module:handle_message/1+ for a description of the other arguments and possible return values. \end{quote} \begin{quote} \textbf{Module:handle\_info(Info, State) -> Result} \begin{verbatim} Info :: timeout | term() State :: term() Result :: {noreply, NewState} | {noreply, NewState, Timeout} | {reply, Reply} | {reply, Reply, NewState} | {reply, Reply, NewState, Timeout} | {close, CloseReason, NewState} | {close, CloseReason, Reply, NewState} NewState :: term() Timeout :: integer() >= 0 | infinity Reply :: see Module:handle_message/1 CloseReason :: see Module:handle_message/1 \end{verbatim} If defined, this function is called when a timeout occurs (see \verb+drop_on_timeout+ option above) or when the handling process receives any unknown message. \verb+Info+ is either the atom \verb+timeout+, if a timeout has occurred, or the received message. See \verb+Module:handle_message/1+ for a description of the other arguments and possible return values. \end{quote} \begin{quote} \textbf{Module:terminate(Reason, State) -> ok} \begin{verbatim} Reason :: Status | {Status, Text} | {error, Error} State :: term() Status :: integer() %% RFC 6455 status code Text :: binary() Error :: term() \end{verbatim} If defined, this function is called when the handling process is about to terminate. it should be the opposite of \verb+Module:init/1+ and do any necessary cleaning up. \verb+Reason+ is a term denoting the stop reason and \verb+State+ is the internal state of the callback module. \end{quote} \subsection{Advanced Callback Modules} Advanced callback modules should be used when automatic messages defragmentation done by \Yaws\ is not desirable or acceptable. One could be used for example to handle data streaming over WebSockets. So, such modules should be prepared to handle frames directly (fragmented or not). Unlike basic callback modules, Advanced ones \textbf{MUST} manage an internal state. So it \textbf{MUST} define the stateful function \verb+Module:handle_message/2+ : \begin{quote} \textbf{Module:handle\_message(Frame, State) -> Result} \begin{verbatim} Frame :: #ws_frame_info{} | {fail_connection, Status, Reason} State :: term() Result :: {noreply, NewState} | {noreply, NewState, Timeout} | {reply, Reply} | {reply, Reply, NewState} | {reply, Reply, NewState, Timeout} | {close, CloseReason, NewState} | {close, CloseReason, Reply, NewState} Status :: integer() %% RFC 6455 status code Reason :: binary() NewState :: term() Timeout :: integer() >= 0 | infinity Reply :: see Module:handle_message/1 CloseReason :: see Module:handle_message/1 \end{verbatim} This function is called when a frame is received. The \verb+#ws_frame_info{}+ record, defined in \verb+include/yaws_api.hrl+, provides all details about this frame. \verb+State+ is the internal state of the callback module. If an error occurs during the frame parsing, the term \verb+{fail_connection, Status, Reason}+ is passed, where \verb+Status+ is the numerical status code corresponding to the error (see RFC 6455 section 7.4.1) and \verb+Reason+ the binary containing optional information about it. This function returns the same values as specified for the basic callback module's \\ \verb+Module:handle_message/2+ function. See section \ref{basic-callback-modules} for details. \end{quote} Advanced callback modules can also define the same optional functions as basic callback modules (except \verb+Module:handle_messages/2+ which is mandatory here, of course). See section \ref{basic-callback-modules} for details. \section{Record definitions} Here is the definition of records used in callback modules, defined in \verb+include/yaws_api.hrl+: \begin{verbatim} %% Corresponds to the frame sections as in %% http://tools.ietf.org/html/rfc6455#section-5.2 %% plus 'data' and 'ws_state'. Used for incoming frames. -record(ws_frame_info, { fin, rsv, opcode, masked, masking_key, length, payload, data, % The unmasked payload. Makes payload redundant. ws_state % The ws_state after unframing this frame. % This is useful for the endpoint to know what type of % fragment a potentially fragmented message is. }). %% Used for outgoing frames. No checks are done on the validity of a frame. This %% is the application's responsability to send valid frames. -record(ws_frame, { fin = true, rsv = 0, opcode, payload = <<>> }). %%---------------------------------------------------------------------- %% The state of a WebSocket connection. %% This is held by the ws owner process and passed in calls to yaws_api. %%---------------------------------------------------------------------- -type frag_type() :: text | binary | none. % The WebSocket is not expecting continuation % of any fragmented message. -record(ws_state, { vsn :: integer(), % WebSocket version number sock, % gen_tcp or gen_ssl socket frag_type :: frag_type() }). \end{verbatim} \end{document} yaws-2.0.2/doc/Makefile.am0000664000175000017500000000331512605311412012217 00000000000000IMG_EPS = a.eps b.eps layout.eps yaws_head.eps IMG_PDF = $(IMG_EPS:.eps=.pdf) EXTRA_DIST = $(IMG_EPS) overview.edoc README.rss yaws.tex if CAN_BUILD_DOC doc: yaws.ps yaws.pdf install-data-local: doc $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(docdir) $(AM_V_at)$(INSTALL) -m 644 yaws.pdf $(DESTDIR)$(docdir) $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(wwwdir) $(AM_V_at)$(INSTALL) -m 644 yaws.ps $(DESTDIR)$(wwwdir) $(AM_V_at)$(INSTALL) -m 644 yaws.pdf $(DESTDIR)$(wwwdir) uninstall-local: $(AM_V_at)rm -f $(DESTDIR)$(docdir)/yaws.pdf $(AM_V_at)rm -f $(DESTDIR)$(wwwdir)/yaws.ps $(AM_V_at)rm -f $(DESTDIR)$(wwwdir)/yaws.pdf clean-local: $(AM_V_at)rm -f *.ps *.dvi *.log *.aux *.pdf *.toc *.out else doc: @echo "SKIPPED:" @if [ -z "$(DVILATEX)" ]; then \ echo " latex required to build documentation"; \ fi @if [ -z "$(DVIPS)" ]; then \ echo " dvips required to build documentation"; \ fi @if [ -z "$(PDFLATEX)" ]; then \ echo " pdflatex required to build documentation"; \ fi @if [ -z "$(EPSTOPDF)" ]; then \ echo " epstopdf required to build documentation"; \ fi install-data-local: doc endif yaws.ps: yaws.dvi $(AM_V_GEN)TEXINPUTS="$${TEXTINPUTS}:@srcdir@" $(DVIPS) -q -o $@ $< yaws.pdf: yaws.tex $(IMG_PDF) $(AM_V_GEN)TEXINPUTS="$${TEXTINPUTS}:@srcdir@" $(PDFLATEX) yaws.tex > /dev/null $(AM_V_at)TEXINPUTS="$${TEXTINPUTS}:@srcdir@" $(PDFLATEX) yaws.tex > /dev/null yaws.dvi: yaws.tex $(IMG_EPS) $(AM_V_GEN)TEXINPUTS="$${TEXTINPUTS}:@srcdir@" $(DVILATEX) yaws.tex > /dev/null $(AM_V_at)TEXINPUTS="$${TEXTINPUTS}:@srcdir@" $(DVILATEX) yaws.tex > /dev/null .eps.pdf: $(AM_V_GEN)$(EPSTOPDF) --outfile=$@ $< > /dev/null .NOTPARALLEL: # Local Variables: # tab-width: 8 # End: yaws-2.0.2/rel/0000775000175000017500000000000012605311412010256 500000000000000yaws-2.0.2/rel/files/0000775000175000017500000000000012605311412011360 500000000000000yaws-2.0.2/rel/files/yaws.cmd0000664000175000017500000000564412605311412012761 00000000000000@setlocal @set node_name=yaws @rem Get the absolute path to the parent directory, @rem which is assumed to be the node root. @for /F "delims=" %%I in ("%~dp0..") do @set node_root=%%~fI @set releases_dir=%node_root%\releases @rem Parse ERTS version and release version from start_erl.data @for /F "usebackq tokens=1,2" %%I in ("%releases_dir%\start_erl.data") do @( @call :set_trim erts_version %%I @call :set_trim release_version %%J ) @set vm_args=%releases_dir%\%release_version%\vm.args @set sys_config=%releases_dir%\%release_version%\sys.config @set node_boot_script=%releases_dir%\%release_version%\%node_name% @set clean_boot_script=%releases_dir%\%release_version%\start_clean @rem extract erlang cookie from vm.args @for /f "usebackq tokens=1-2" %%I in (`findstr /b \-setcookie "%vm_args%"`) do @set erlang_cookie=%%J @set erts_bin=%node_root%\erts-%erts_version%\bin @set service_name=%node_name%_%release_version% @set erlsrv="%erts_bin%\erlsrv.exe" @set epmd="%erts_bin%\epmd.exe" @set escript="%erts_bin%\escript.exe" @set werl="%erts_bin%\werl.exe" @set nodetool="%erts_bin%\nodetool" @if "%1"=="usage" @goto usage @if "%1"=="install" @goto install @if "%1"=="uninstall" @goto uninstall @if "%1"=="start" @goto start @if "%1"=="stop" @goto stop @if "%1"=="restart" @call :stop && @goto start @if "%1"=="console" @goto console @if "%1"=="ping" @goto ping @if "%1"=="query" @goto query @if "%1"=="attach" @goto attach @if "%1"=="upgrade" @goto upgrade @echo Unknown command: "%1" :usage @echo Usage: %~n0 [install^|uninstall^|start^|stop^|restart^|console^|ping^|query^|attach^|upgrade] @goto :EOF :install @set description=Erlang node %node_name% in %node_root% @set start_erl=%node_root%\bin\start_erl.cmd @set args= ++ %node_name% ++ %node_root% @%erlsrv% add %service_name% -c "%description%" -sname %node_name% -w "%node_root%" -m "%start_erl%" -args "%args%" -stopaction "init:stop()." @goto :EOF :uninstall @%erlsrv% remove %service_name% @%epmd% -kill @goto :EOF :start @%erlsrv% start %service_name% @goto :EOF :stop @%erlsrv% stop %service_name% @goto :EOF :console @start "%node_name% console" %werl% -boot "%node_boot_script%" -config "%sys_config%" -args_file "%vm_args%" -sname %node_name% @goto :EOF :ping @%escript% %nodetool% ping -sname "%node_name%" -setcookie "%erlang_cookie%" @exit %ERRORLEVEL% @goto :EOF :query @%erlsrv% list %service_name% @exit %ERRORLEVEL% @goto :EOF :attach @for /f "usebackq" %%I in (`hostname`) do @set hostname=%%I start "%node_name% attach" %werl% -boot "%clean_boot_script%" -remsh %node_name%@%hostname% -sname console -setcookie %erlang_cookie% @goto :EOF :upgrade @if "%2"=="" ( @echo Missing upgrade package argument @echo Usage: %~n0 upgrade {package base name} @echo NOTE {package base name} MUST NOT include the .tar.gz suffix @goto :EOF ) @%escript% %node_root%\bin\install_upgrade.escript %node_name% %erlang_cookie% %2 @goto :EOF :set_trim @set %1=%2 @goto :EOF yaws-2.0.2/rel/files/nodetool0000775000175000017500000001447212605311412013061 00000000000000#!/usr/bin/env escript %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ft=erlang ts=4 sw=4 et %% ------------------------------------------------------------------- %% %% nodetool: Helper Script for interacting with live nodes %% %% ------------------------------------------------------------------- main(Args) -> ok = start_epmd(), %% Extract the args {RestArgs, TargetNode} = process_args(Args, [], undefined), %% any commands that don't need a running node case RestArgs of ["chkconfig", File] -> case file:consult(File) of {ok, _} -> io:format("ok\n"), halt(0); {error, {Line, Mod, Term}} -> io:format(standard_error, ["Error on line ", file:format_error({Line, Mod, Term}), "\n"], []), halt(1); {error, R} -> io:format(standard_error, ["Error reading config file: ", file:format_error(R), "\n"], []), halt(1) end; _ -> ok end, %% See if the node is currently running -- if it's not, we'll bail case {net_kernel:hidden_connect_node(TargetNode), net_adm:ping(TargetNode)} of {true, pong} -> ok; {false,pong} -> io:format("Failed to connect to node ~p .\n", [TargetNode]), halt(1); {_, pang} -> io:format("Node ~p not responding to pings.\n", [TargetNode]), halt(1) end, case RestArgs of ["getpid"] -> io:format("~p\n", [list_to_integer(rpc:call(TargetNode, os, getpid, []))]); ["ping"] -> %% If we got this far, the node already responsed to a %% ping, so just dump a "pong" io:format("pong\n"); ["stop"] -> io:format("~p\n", [rpc:call(TargetNode, init, stop, [], 60000)]); ["restart"] -> io:format("~p\n", [rpc:call(TargetNode, init, restart, [], 60000)]); ["reboot"] -> io:format("~p\n", [rpc:call(TargetNode, init, reboot, [], 60000)]); ["rpc", Module, Function | RpcArgs] -> case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), [RpcArgs], 60000) of ok -> ok; {badrpc, Reason} -> io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]), halt(1); _ -> halt(1) end; ["rpc_infinity", Module, Function | RpcArgs] -> case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), [RpcArgs], infinity) of ok -> ok; {badrpc, Reason} -> io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]), halt(1); _ -> halt(1) end; ["rpcterms", Module, Function, ArgsAsString] -> case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), consult(ArgsAsString), 60000) of {badrpc, Reason} -> io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]), halt(1); Other -> io:format("~p\n", [Other]) end; Other -> io:format("Other: ~p\n", [Other]), io:format("Usage: nodetool {chkconfig|getpid|ping|stop|restart|reboot|rpc|rpc_infinity|rpcterms}\n") end, net_kernel:stop(). process_args([], Acc, TargetNode) -> {lists:reverse(Acc), TargetNode}; process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) -> erlang:set_cookie(node(), list_to_atom(Cookie)), process_args(Rest, Acc, TargetNode); process_args(["-name", TargetName | Rest], Acc, _) -> ThisNode = append_node_suffix(TargetName, "_maint_"), {ok, _} = net_kernel:start([ThisNode, longnames]), process_args(Rest, Acc, nodename(TargetName)); process_args(["-sname", TargetName | Rest], Acc, _) -> ThisNode = append_node_suffix(TargetName, "_maint_"), {ok, _} = net_kernel:start([ThisNode, shortnames]), process_args(Rest, Acc, nodename(TargetName)); process_args([Arg | Rest], Acc, Opts) -> process_args(Rest, [Arg | Acc], Opts). start_epmd() -> [] = os:cmd(epmd_path() ++ " -daemon"), ok. epmd_path() -> ErtsBinDir = filename:dirname(escript:script_name()), Name = "epmd", case os:find_executable(Name, ErtsBinDir) of false -> case os:find_executable(Name) of false -> io:format("Could not find epmd.~n"), halt(1); GlobalEpmd -> GlobalEpmd end; Epmd -> Epmd end. nodename(Name) -> case string:tokens(Name, "@") of [_Node, _Host] -> list_to_atom(Name); [Node] -> [_, Host] = string:tokens(atom_to_list(node()), "@"), list_to_atom(lists:concat([Node, "@", Host])) end. append_node_suffix(Name, Suffix) -> case string:tokens(Name, "@") of [Node, Host] -> list_to_atom(lists:concat([Node, Suffix, os:getpid(), "@", Host])); [Node] -> list_to_atom(lists:concat([Node, Suffix, os:getpid()])) end. %% %% Given a string or binary, parse it into a list of terms, ala file:consult/0 %% consult(Str) when is_list(Str) -> consult([], Str, []); consult(Bin) when is_binary(Bin)-> consult([], binary_to_list(Bin), []). consult(Cont, Str, Acc) -> case erl_scan:tokens(Cont, Str, 0) of {done, Result, Remaining} -> case Result of {ok, Tokens, _} -> {ok, Term} = erl_parse:parse_term(Tokens), consult([], Remaining, [Term | Acc]); {eof, _Other} -> lists:reverse(Acc); {error, Info, _} -> {error, Info} end; {more, Cont1} -> consult(Cont1, eof, Acc) end. yaws-2.0.2/rel/files/erl0000775000175000017500000000262112605311412012011 00000000000000#!/bin/sh # /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is. if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then POSIX_SHELL="true" export POSIX_SHELL exec /usr/bin/ksh $0 "$@" fi # clear it so if we invoke other scripts, they run as ksh as well unset POSIX_SHELL ## This script replaces the default "erl" in erts-VSN/bin. This is ## necessary as escript depends on erl and in turn, erl depends on ## having access to a bootscript (start.boot). Note that this script ## is ONLY invoked as a side-effect of running escript -- the embedded ## node bypasses erl and uses erlexec directly (as it should). ## ## Note that this script makes the assumption that there is a ## start_clean.boot file available in $ROOTDIR/release/VSN. # Determine the abspath of where this script is executing from. ERTS_BIN_DIR=$(cd ${0%/*} && pwd -P) # Now determine the root directory -- this script runs from erts-VSN/bin, # so we simply need to strip off two dirs from the end of the ERTS_BIN_DIR # path. ROOTDIR=${ERTS_BIN_DIR%/*/*} # Parse out release and erts info START_ERL=`cat $ROOTDIR/releases/start_erl.data` ERTS_VSN=${START_ERL% *} APP_VSN=${START_ERL#* } BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin EMU=beam PROGNAME=`echo $0 | sed 's/.*\\///'` CMD="$BINDIR/erlexec" export EMU export ROOTDIR export BINDIR export PROGNAME exec $CMD -boot $ROOTDIR/releases/$APP_VSN/start_clean ${1+"$@"} yaws-2.0.2/rel/files/yaws0000775000175000017500000002236712605311412012223 00000000000000#!/bin/sh # -*- tab-width:4;indent-tabs-mode:nil -*- # ex: ts=4 sw=4 et # /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is. if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then POSIX_SHELL="true" export POSIX_SHELL # To support 'whoami' add /usr/ucb to path PATH=/usr/ucb:$PATH export PATH exec /usr/bin/ksh $0 "$@" fi # clear it so if we invoke other scripts, they run as ksh unset POSIX_SHELL RUNNER_SCRIPT_DIR=$(cd ${0%/*} && pwd -P) CALLER_DIR=$PWD RUNNER_BASE_DIR=${RUNNER_SCRIPT_DIR%/*} RUNNER_ETC_DIR=$RUNNER_BASE_DIR/etc # Note the trailing slash on $PIPE_DIR/ PIPE_DIR=/tmp/$RUNNER_BASE_DIR/ RUNNER_USER= WHOAMI=$(whoami) # Make sure this script is running as the appropriate user if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then type sudo > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "sudo doesn't appear to be installed and your EUID isn't $RUNNER_USER" 1>&2 exit 1 fi echo "Attempting to restart script through sudo -H -u $RUNNER_USER" >&2 exec sudo -H -u $RUNNER_USER -i $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $@ fi # Identify the script name SCRIPT=`basename $0` # Parse out release and erts info START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data` ERTS_VSN=${START_ERL% *} APP_VSN=${START_ERL#* } # Use $CWD/vm.args if exists, otherwise releases/APP_VSN/vm.args, or # else etc/vm.args if [ -e "$CALLER_DIR/vm.args" ]; then VMARGS_PATH=$CALLER_DIR/vm.args USE_DIR=$CALLER_DIR else USE_DIR=$RUNNER_BASE_DIR if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/vm.args" ]; then VMARGS_PATH="$RUNNER_BASE_DIR/releases/$APP_VSN/vm.args" else VMARGS_PATH="$RUNNER_ETC_DIR/vm.args" fi fi RUNNER_LOG_DIR=$USE_DIR/log # Make sure log directory exists mkdir -p $RUNNER_LOG_DIR # Use releases/VSN/sys.config if it exists otherwise use etc/app.config if [ -e "$USE_DIR/sys.config" ]; then CONFIG_PATH="$USE_DIR/sys.config" else if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/sys.config" ]; then CONFIG_PATH="$RUNNER_BASE_DIR/releases/$APP_VSN/sys.config" else CONFIG_PATH="$RUNNER_ETC_DIR/app.config" fi fi # Extract the target node name from node.args NAME_ARG=`egrep '^\-s?name' $VMARGS_PATH` if [ -z "$NAME_ARG" ]; then echo "vm.args needs to have either -name or -sname parameter." exit 1 fi # Extract the name type and name from the NAME_ARG for REMSH REMSH_TYPE=`echo $NAME_ARG | awk '{print $1}'` REMSH_NAME=`echo $NAME_ARG | awk '{print $2}'` # Note the `date +%s`, used to allow multiple remsh to the same node # transparently REMSH_NAME_ARG="$REMSH_TYPE remsh`date +%s`@`echo $REMSH_NAME | awk -F@ '{print $2}'`" REMSH_REMSH_ARG="-remsh $REMSH_NAME" # Extract the target cookie COOKIE_ARG=`grep '^\-setcookie' $VMARGS_PATH` if [ -z "$COOKIE_ARG" ]; then echo "vm.args needs to have a -setcookie parameter." exit 1 fi # Make sure CWD is set to the right dir cd $USE_DIR # Make sure log directory exists mkdir -p $USE_DIR/log # Add ERTS bin dir to our path ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin # Setup command to control the node NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG" # Setup remote shell command to control node REMSH="$ERTS_PATH/erl $REMSH_NAME_ARG $REMSH_REMSH_ARG $COOKIE_ARG" # Common functions # Ping node without allowing nodetool to take stdin ping_node() { $NODETOOL ping < /dev/null } # Set the PID global variable, return 1 on error get_pid() { PID=`$NODETOOL getpid < /dev/null` ES=$? if [ "$ES" -ne 0 ]; then echo "Node is not running!" return 1 fi # don't allow empty or init pid's if [ -z $PID ] || [ "$PID" -le 1 ]; then return 1 fi return 0 } # Check the first argument for instructions case "$1" in start|start_boot) # Make sure there is not already a node running RES=`ping_node` if [ "$RES" = "pong" ]; then echo "Node is already running!" exit 1 fi case "$1" in start) shift START_OPTION="console" HEART_OPTION="start" ;; start_boot) shift START_OPTION="console_boot" HEART_OPTION="start_boot" ;; esac RUN_PARAM=$(printf "\'%s\' " "$@") HEART_COMMAND="$RUNNER_BASE_DIR/bin/$SCRIPT $HEART_OPTION $RUN_PARAM" export HEART_COMMAND mkdir -p $PIPE_DIR $ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT $START_OPTION $RUN_PARAM" 2>&1 ;; stop) # Wait for the node to completely stop... case `uname -s` in Darwin) # Make sure we explicitly set this because iTerm.app doesn't for # some reason. COMMAND_MODE=unix2003 esac # Get the PID from nodetool get_pid GPR=$? if [ "$GPR" -ne 0 ] || [ -z $PID ]; then exit $GPR fi # Tell nodetool to initiate a stop $NODETOOL stop ES=$? if [ "$ES" -ne 0 ]; then exit $ES fi # Wait for the node to completely stop... while `kill -s 0 $PID 2>/dev/null` do sleep 1 done ;; restart) ## Restart the VM without exiting the process $NODETOOL restart ES=$? if [ "$ES" -ne 0 ]; then exit $ES fi ;; reboot) ## Restart the VM completely (uses heart to restart it) $NODETOOL reboot ES=$? if [ "$ES" -ne 0 ]; then exit $ES fi ;; ping) ## See if the VM is alive ping_node ES=$? if [ "$ES" -ne 0 ]; then exit $ES fi ;; attach) # Make sure a node is running ping_node ES=$? if [ "$ES" -ne 0 ]; then echo "Node is not running!" exit $ES fi shift exec $ERTS_PATH/to_erl $PIPE_DIR ;; remote_console) # Make sure a node is running ping_node ES=$? if [ "$ES" -ne 0 ]; then echo "Node is not running!" exit $ES fi shift exec $REMSH ;; upgrade) if [ -z "$2" ]; then echo "Missing upgrade package argument" echo "Usage: $SCRIPT upgrade {package base name}" echo "NOTE {package base name} MUST NOT include the .tar.gz suffix" exit 1 fi # Make sure a node IS running ping_node ES=$? if [ "$ES" -ne 0 ]; then echo "Node is not running!" exit $ES fi node_name=`echo $NAME_ARG | awk '{print $2}'` erlang_cookie=`echo $COOKIE_ARG | awk '{print $2}'` $ERTS_PATH/escript $RUNNER_BASE_DIR/bin/install_upgrade.escript $node_name $erlang_cookie $2 ;; console|console_clean|console_boot) # .boot file typically just $SCRIPT (ie, the app name) # however, for debugging, sometimes start_clean.boot is useful. # For e.g. 'setup', one may even want to name another boot script. case "$1" in console) BOOTFILE=$SCRIPT ;; console_clean) BOOTFILE=start_clean ;; console_boot) shift BOOTFILE="$1" shift ;; esac # Setup beam-required vars ROOTDIR=$RUNNER_BASE_DIR BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin EMU=beam PROGNAME=`echo $0 | sed 's/.*\\///'` CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$BOOTFILE -mode embedded -config $CONFIG_PATH -args_file $VMARGS_PATH" export EMU export ROOTDIR export BINDIR export PROGNAME # Dump environment info for logging purposes echo "Exec: $CMD" -- ${1+"$@"} echo "Root: $ROOTDIR" # Log the startup logger -t "$SCRIPT[$$]" "Starting up" # Start the VM exec $CMD -- ${1+"$@"} ;; foreground) # start up the release in the foreground for use by runit # or other supervision services BOOTFILE=$SCRIPT FOREGROUNDOPTIONS="-noinput +Bd" # Setup beam-required vars ROOTDIR=$RUNNER_BASE_DIR BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin EMU=beam PROGNAME=`echo $0 | sed 's/.*\///'` CMD="$BINDIR/erlexec $FOREGROUNDOPTIONS -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$BOOTFILE -config $CONFIG_PATH -args_file $VMARGS_PATH" export EMU export ROOTDIR export BINDIR export PROGNAME # Dump environment info for logging purposes echo "Exec: $CMD" -- ${1+"$@"} echo "Root: $ROOTDIR" # Start the VM exec $CMD -- ${1+"$@"} ;; getpid) # Get the PID from nodetool get_pid ES=$? if [ "$ES" -ne 0 ] || [ -z $PID ]; then exit $ES fi echo $PID ;; *) echo "Usage: $SCRIPT {start|start_boot |foreground|stop|restart|reboot|ping|console|getpid|console_clean|console_boot |attach|remote_console|upgrade}" exit 1 ;; esac exit 0 yaws-2.0.2/rel/files/vm.args0000664000175000017500000000064012605311412012600 00000000000000## Name of the node -name yaws@127.0.0.1 ## Cookie for distributed erlang -setcookie yaws ## Heartbeat management; auto-restarts VM if it dies or becomes unresponsive ## (Disabled by default..use with caution!) ##-heart ## Enable kernel poll and a few async threads +K true +A 5 ## Increase number of concurrent ports/sockets -env ERL_MAX_PORTS 4096 ## Tweak GC to run more often ## -env ERL_FULLSWEEP_AFTER 10 yaws-2.0.2/rel/files/sys.config0000664000175000017500000000051512605311412013306 00000000000000[ %% SASL config {sasl, [ {sasl_error_logger, {file, "log/sasl-error.log"}}, {errlog_type, error}, {error_logger_mf_dir, "log/sasl"}, % Log directory {error_logger_mf_maxbytes, 10485760}, % 10 MB max file size {error_logger_mf_maxfiles, 5} % 5 files max ]} ]. yaws-2.0.2/rel/files/start_erl.cmd0000664000175000017500000000235412605311412013770 00000000000000@setlocal @rem Parse arguments. erlsrv.exe prepends erl arguments prior to first ++. @rem Other args are position dependent. @set args="%*" @for /F "delims=++ tokens=1,2,3" %%I in (%args%) do @( @set erl_args=%%I @call :set_trim node_name %%J @rem Trim spaces from the left of %%K (node_root), which may have spaces inside @for /f "tokens=* delims= " %%a in ("%%K") do @set node_root=%%a ) @set releases_dir=%node_root%\releases @rem parse ERTS version and release version from start_erl.dat @for /F "usebackq tokens=1,2" %%I in ("%releases_dir%\start_erl.data") do @( @call :set_trim erts_version %%I @call :set_trim release_version %%J ) @set erl_exe="%node_root%\erts-%erts_version%\bin\erl.exe" @set boot_file="%releases_dir%\%release_version%\%node_name%" @if exist "%releases_dir%\%release_version%\sys.config" ( @set app_config="%releases_dir%\%release_version%\sys.config" ) else ( @set app_config="%node_root%\etc\app.config" ) @if exist "%releases_dir%\%release_version%\vm.args" ( @set vm_args="%releases_dir%\%release_version%\vm.args" ) else ( @set vm_args="%node_root%\etc\vm.args" ) @%erl_exe% %erl_args% -boot %boot_file% -config %app_config% -args_file %vm_args% :set_trim @set %1=%2 @goto :EOF yaws-2.0.2/rel/files/install_upgrade.escript0000664000175000017500000000325612605311412016056 00000000000000#!/usr/bin/env escript %%! -noshell -noinput %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ft=erlang ts=4 sw=4 et -define(TIMEOUT, 60000). -define(INFO(Fmt,Args), io:format(Fmt,Args)). main([NodeName, Cookie, ReleasePackage]) -> TargetNode = start_distribution(NodeName, Cookie), {ok, Vsn} = rpc:call(TargetNode, release_handler, unpack_release, [ReleasePackage], ?TIMEOUT), ?INFO("Unpacked Release ~p~n", [Vsn]), {ok, OtherVsn, Desc} = rpc:call(TargetNode, release_handler, check_install_release, [Vsn], ?TIMEOUT), {ok, OtherVsn, Desc} = rpc:call(TargetNode, release_handler, install_release, [Vsn], ?TIMEOUT), ?INFO("Installed Release ~p~n", [Vsn]), ok = rpc:call(TargetNode, release_handler, make_permanent, [Vsn], ?TIMEOUT), ?INFO("Made Release ~p Permanent~n", [Vsn]); main(_) -> init:stop(1). start_distribution(NodeName, Cookie) -> MyNode = make_script_node(NodeName), {ok, _Pid} = net_kernel:start([MyNode, shortnames]), erlang:set_cookie(node(), list_to_atom(Cookie)), TargetNode = make_target_node(NodeName), case {net_kernel:hidden_connect_node(TargetNode), net_adm:ping(TargetNode)} of {true, pong} -> ok; {_, pang} -> io:format("Node ~p not responding to pings.\n", [TargetNode]), init:stop(1) end, TargetNode. make_target_node(Node) -> [_, Host] = string:tokens(atom_to_list(node()), "@"), list_to_atom(lists:concat([Node, "@", Host])). make_script_node(Node) -> list_to_atom(lists:concat([Node, "_upgrader_", os:getpid()])). yaws-2.0.2/rel/reltool.config0000664000175000017500000000267712605311412013061 00000000000000{sys, [ {erts, [{mod_cond, derived}, {app_file, strip}]}, {app_file, strip}, {rel, "yaws", {cmd, "sed -ne '1,/^YAWS_VSN=/s/^YAWS_VSN=//p' ../vsn.mk 2>/dev/null"}, [ kernel, stdlib, sasl, crypto, ssl, public_key, compiler, mnesia, xmerl, yaws ]}, {rel, "start_clean", "", [ kernel, stdlib ]}, {boot_rel, "yaws"}, {profile, embedded}, {incl_cond, derived}, {mod_cond, derived}, {excl_archive_filters, [".*"]}, %% Do not archive built libs {excl_sys_filters, ["^bin/.*", "^erts.*/bin/(dialyzer|typer)", "^erts.*/(doc|info|include|lib|man|src)"]}, {excl_app_filters, ["\.gitignore", "^include.mk.in"]}, {app, hipe, [{incl_cond, exclude}]}, {app, yaws, [{mod_cond, app}, {incl_cond, include}, {lib_dir, ".."}]} ]}. {target_dir, "yaws"}. {overlay, [ {mkdir, "log/sasl"}, {copy, "files/erl", "\{\{erts_vsn\}\}/bin/erl"}, {copy, "files/nodetool", "\{\{erts_vsn\}\}/bin/nodetool"}, {copy, "files/yaws", "bin/yaws"}, {copy, "files/install_upgrade.escript", "bin/install_upgrade.escript"}, {copy, "files/sys.config", "releases/\{\{rel_vsn\}\}/sys.config"}, {copy, "files/vm.args", "releases/\{\{rel_vsn\}\}/vm.args"} ]}. yaws-2.0.2/include/0000775000175000017500000000000012605312014011116 500000000000000yaws-2.0.2/include/Makefile.in0000664000175000017500000004137212605311446013122 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = include DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(dist_inc_DATA) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(incdir)" DATA = $(dist_inc_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ incdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/include dist_inc_DATA = yaws_api.hrl \ yaws_dav.hrl \ yaws.hrl \ yaws_lock.hrl \ yaws_soap.hrl \ soap.hrl \ wsdl11soap12.hrl \ soap-envelope.hrl all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign include/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_incDATA: $(dist_inc_DATA) @$(NORMAL_INSTALL) @list='$(dist_inc_DATA)'; test -n "$(incdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(incdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(incdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(incdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(incdir)" || exit $$?; \ done uninstall-dist_incDATA: @$(NORMAL_UNINSTALL) @list='$(dist_inc_DATA)'; test -n "$(incdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(incdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(incdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_incDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_incDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-dist_incDATA install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-dist_incDATA # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/include/soap.hrl0000664000175000017500000000744412605311412012521 00000000000000-record(wsdl, {operations, model, module}). -record(port, {service, port, binding, address}). -record(operation, {service, port, operation, binding, address, action}). -record('soap:detail', {anyAttribs, choice}). -record('soap:Fault', {anyAttribs, 'faultcode', 'faultstring', 'faultactor', 'detail'}). -record('soap:Body', {anyAttribs, choice}). -record('soap:Header', {anyAttribs, choice}). -record('soap:Envelope', {anyAttribs, 'Header', 'Body', choice}). -record('wsdl:tExtensibilityElement', {anyAttribs, 'wsdl:required'}). -record('wsdl:tPort', {anyAttribs, 'name', 'binding', 'documentation', choice}). -record('wsdl:tService', {anyAttribs, 'name', 'documentation', choice, 'port'}). -record('wsdl:tBindingOperation', {anyAttribs, 'name', 'documentation', choice, 'input', 'output', 'fault'}). -record('wsdl:tBindingOperationFault', {anyAttribs, 'name', 'documentation', choice}). -record('wsdl:tBindingOperationMessage', {anyAttribs, 'name', 'documentation', choice}). -record('wsdl:tBinding', {anyAttribs, 'name', 'type', 'documentation', choice, 'operation'}). -record('wsdl:tFault', {anyAttribs, 'name', 'message', 'documentation'}). -record('wsdl:tParam', {anyAttribs, 'name', 'message', 'documentation'}). -record('wsdl:solicit-response-or-notification-operation', {anyAttribs, 'output', 'solicit-response-or-notification-operation/SEQ2'}). -record('wsdl:solicit-response-or-notification-operation/SEQ2', {anyAttribs, 'input', 'fault'}). -record('wsdl:request-response-or-one-way-operation', {anyAttribs, 'input', 'request-response-or-one-way-operation/SEQ1'}). -record('wsdl:request-response-or-one-way-operation/SEQ1', {anyAttribs, 'output', 'fault'}). -record('wsdl:tOperation', {anyAttribs, 'name', 'parameterOrder', 'documentation', any, choice}). -record('wsdl:tPortType', {anyAttribs, 'name', 'documentation', 'operation'}). -record('wsdl:tPart', {anyAttribs, 'name', 'element', 'type', 'documentation'}). -record('wsdl:tMessage', {anyAttribs, 'name', 'documentation', choice, 'part'}). -record('wsdl:tTypes', {anyAttribs, 'documentation', choice}). -record('wsdl:tImport', {anyAttribs, 'namespace', 'location', 'documentation'}). -record('wsdl:tDefinitions', {anyAttribs, 'targetNamespace', 'name', 'documentation', any, choice}). -record('wsdl:anyTopLevelOptionalElement-service', {anyAttribs, 'service'}). -record('wsdl:anyTopLevelOptionalElement-binding', {anyAttribs, 'binding'}). -record('wsdl:anyTopLevelOptionalElement-portType', {anyAttribs, 'portType'}). -record('wsdl:anyTopLevelOptionalElement-message', {anyAttribs, 'message'}). -record('wsdl:anyTopLevelOptionalElement-types', {anyAttribs, 'types'}). -record('wsdl:anyTopLevelOptionalElement-import', {anyAttribs, 'import'}). -record('wsdl:anyTopLevelOptionalElement', {anyAttribs, choice}). -record('wsdl:tExtensibleDocumented', {anyAttribs, 'documentation', choice}). -record('wsdl:tExtensibleAttributesDocumented', {anyAttribs, 'documentation'}). -record('wsdl:tDocumented', {anyAttribs, 'documentation'}). -record('wsdl:tDocumentation-any', {anyAttribs, choice}). -record('wsdl:tDocumentation', {anyAttribs, choice}). -record('soap:tBinding', {anyAttribs, 'wsdl:required', 'transport', 'style'}). -record('soap:tOperation', {anyAttribs, 'wsdl:required', 'soapAction', 'style'}). -record('soap:tBody', {anyAttribs, 'wsdl:required', 'parts', 'namespace', 'use', 'encodingStyle'}). -record('soap:tFaultRes', {anyAttribs, 'wsdl:required', 'parts', 'namespace', 'use', 'encodingStyle'}). -record('soap:tFault', {anyAttribs, 'wsdl:required', 'parts', 'namespace', 'use', 'encodingStyle', 'name'}). -record('soap:tHeader', {anyAttribs, 'wsdl:required', 'namespace', 'encodingStyle', 'use', 'part', 'message', 'headerfault'}). -record('soap:tHeaderFault', {anyAttribs, 'namespace', 'encodingStyle', 'use', 'part', 'message'}). -record('soap:tAddress', {anyAttribs, 'wsdl:required', 'location'}). yaws-2.0.2/include/yaws_dav.hrl0000664000175000017500000000047012605311412013364 00000000000000-ifndef(_YAWS_DAV). -define(_YAWS_DAV, true). -record(resource,{ name, % normalized name of resource info % file_info record of mapped file }). -record(upload, { fd, tempname, filename }). -endif. yaws-2.0.2/include/soap-envelope.hrl0000664000175000017500000000160612605311412014326 00000000000000%% HRL file generated by ERLSOM %% %% It is possible to change the name of the record fields. %% %% It is possible to add default values, but be aware that these will %% only be used when *writing* an xml document. -record('soap:UpgradeType', {anyAttribs, 'SupportedEnvelope'}). -record('soap:SupportedEnvType', {anyAttribs, 'qname'}). -record('soap:NotUnderstoodType', {anyAttribs, 'qname'}). -record('soap:detail', {anyAttribs, choice}). -record('soap:subcode', {anyAttribs, 'Value', 'Subcode'}). -record('soap:faultcode', {anyAttribs, 'Value', 'Subcode'}). -record('soap:reasontext', {anyAttribs, 'P:lang', '#text'}). -record('soap:faultreason', {anyAttribs, 'Text'}). -record('soap:Fault', {anyAttribs, 'Code', 'Reason', 'Node', 'Role', 'Detail'}). -record('soap:Body', {anyAttribs, choice}). -record('soap:Header', {anyAttribs, choice}). -record('soap:Envelope', {anyAttribs, 'Header', 'Body'}). yaws-2.0.2/include/yaws_soap.hrl0000664000175000017500000000025012605311412013550 00000000000000-record(wsdl, {operations, model, module}). -record(port, {service, port, binding, address}). -record(operation, {service, port, operation, binding, address, action}). yaws-2.0.2/include/yaws_lock.hrl0000664000175000017500000000114412605311412013541 00000000000000-ifndef(_YAWS_LOCK). -define(_YAWS_LOCK, true). -define(LOCK_LIFETIME, 900). % lock lifetime in seconds: 15 minutes -define(CLEANUP_INTERVAL, 60). % cleanup interval in seconds: 1 minute -record(lock,{ path=undefined, % resource path id=undefined, % uid owner=anonymous, % lock owner if submitted depth=infinity, % 0|infinity scope=exclusive, % exclusive|shared type=write, % write timeout=0, % ?LOCK_LIFETIME or shorter timestamp=0 % erlang:now() }). -endif. yaws-2.0.2/include/yaws_api.hrl0000664000175000017500000001267312605311412013373 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_api.hrl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 24 Jan 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -author('klacke@hyber.org'). -record(arg, { clisock, % the socket leading to the peer client client_ip_port, % {ClientIp, ClientPort} tuple headers, % headers req, % request (possibly rewritten) orig_req, % original request clidata, % The client data (as a binary in POST requests) server_path, % The normalized server path % (pre-querystring part of URI) querydata, % For URIs of the form ...?querydata % equiv of cgi QUERY_STRING appmoddata, % (deprecated - use pathinfo instead) the remainder % of the path leading up to the query docroot, % Physical base location of data for this request docroot_mount, % virtual directory e.g /myapp/ that the docroot % refers to. fullpath, % full deep path to yaws file cont, % Continuation for chunked multipart uploads state, % State for use by users of the out/1 callback pid, % pid of the yaws worker process opaque, % useful to pass static data appmod_prepath, % (deprecated - use prepath instead) path in front % of: prepath, % Path prior to 'dynamic' segment of URI. % ie http://some.host///d/e % where is an appmod mount point, % or .yaws,.php,.cgi,.fcgi etc script file. pathinfo % Set to '/d/e' when calling c.yaws for the request % http://some.host/a/b/c.yaws/d/e % equiv of cgi PATH_INFO }). -record(http_request, {method, path, version}). -record(http_response, {version, status, phrase}). -record(rewrite_response, {status, headers = [], content = <<>>}). -record(headers, { connection, accept, host, if_modified_since, if_match, if_none_match, if_range, if_unmodified_since, range, referer, user_agent, accept_ranges, cookie = [], keep_alive, location, content_length, content_type, content_encoding, authorization, transfer_encoding, x_forwarded_for, other = [] % misc other headers }). -record(url, {scheme, % undefined means not set host, % undefined means not set port, % undefined means not set path = [], querypart = []}). -record(setcookie, {key, value, quoted = false, domain, max_age, expires, path, secure = false, http_only = false, extensions = []}). -record(cookie, {key, value, quoted = false}). -record(redir_self, { host, % string() - our own host scheme, % http | https scheme_str, % "https://" | "http://" port, % integer() - our own port port_str % "" | ":" - the optional port part % to append to the url }). %% Corresponds to the frame sections as in %% http://tools.ietf.org/html/rfc6455#section-5.2 %% plus 'data' and 'ws_state'. Used for incoming frames. -record(ws_frame_info, { fin, rsv, opcode, masked, masking_key, length, payload, data, % The unmasked payload. Makes payload redundant. ws_state % The ws_state after unframing this frame. % This is useful for the endpoint to know what type of % fragment a potentially fragmented message is. }). %% Used for outgoing frames. No checks are done on the validity of a frame. This %% is the application's responsability to send valid frames. -record(ws_frame, { fin = true, rsv = 0, opcode, payload = <<>> }). %%---------------------------------------------------------------------- %% The state of a WebSocket connection. %% This is held by the ws owner process and passed in calls to yaws_api. %%---------------------------------------------------------------------- -type frag_type() :: text | binary | none. % The WebSocket is not expecting continuation % of any fragmented message. -record(ws_state, { vsn :: integer(), % WebSocket version number sock, % gen_tcp or gen_ssl socket frag_type :: frag_type() }). yaws-2.0.2/include/wsdl11soap12.hrl0000664000175000017500000000623212605311412013712 00000000000000%% HRL file generated by ERLSOM %% %% It is possible to change the name of the record fields. %% %% It is possible to add default values, but be aware that these will %% only be used when *writing* an xml document. -record('soap:tAddress', {anyAttribs, 'wsdl:required', 'location'}). -record('soap:tHeaderFault', {anyAttribs, 'message', 'part', 'use', 'encodingStyle', 'namespace'}). -record('soap:tHeader', {anyAttribs, 'wsdl:required', 'message', 'part', 'use', 'encodingStyle', 'namespace', 'headerfault'}). -record('soap:tFault', {anyAttribs, 'wsdl:required', 'parts', 'encodingStyle', 'use', 'namespace', 'name'}). -record('soap:tFaultRes', {anyAttribs, 'wsdl:required', 'parts', 'encodingStyle', 'use', 'namespace'}). -record('soap:tBody', {anyAttribs, 'wsdl:required', 'parts', 'encodingStyle', 'use', 'namespace'}). -record('soap:tOperation', {anyAttribs, 'wsdl:required', 'soapAction', 'soapActionRequired', 'style'}). -record('soap:tBinding', {anyAttribs, 'wsdl:required', 'transport', 'style'}). -record('soap:tExtensibilityElementOpenAttrs', {anyAttribs, 'wsdl:required'}). -record('wsdl:tDocumentation', {anyAttribs, choice}). -record('wsdl:tDocumented', {anyAttribs, 'documentation'}). -record('wsdl:tExtensibleAttributesDocumented', {anyAttribs, 'documentation'}). -record('wsdl:tExtensibleDocumented', {anyAttribs, 'documentation', choice}). -record('wsdl:anyTopLevelOptionalElement', {anyAttribs, choice}). -record('wsdl:tDefinitions', {anyAttribs, 'targetNamespace', 'name', 'documentation', choice, choice1}). -record('wsdl:tImport', {anyAttribs, 'namespace', 'location', 'documentation'}). -record('wsdl:tTypes', {anyAttribs, 'documentation', choice}). -record('wsdl:tMessage', {anyAttribs, 'name', 'documentation', choice, 'part'}). -record('wsdl:tPart', {anyAttribs, 'name', 'element', 'type', 'documentation'}). -record('wsdl:tPortType', {anyAttribs, 'name', 'documentation', 'operation'}). -record('wsdl:tOperation', {anyAttribs, 'name', 'parameterOrder', 'documentation', choice, choice1}). -record('wsdl:request-response-or-one-way-operation/SEQ1', {anyAttribs, 'output', 'fault'}). -record('wsdl:request-response-or-one-way-operation', {anyAttribs, 'input', 'request-response-or-one-way-operation/SEQ1'}). -record('wsdl:solicit-response-or-notification-operation/SEQ2', {anyAttribs, 'input', 'fault'}). -record('wsdl:solicit-response-or-notification-operation', {anyAttribs, 'output', 'solicit-response-or-notification-operation/SEQ2'}). -record('wsdl:tParam', {anyAttribs, 'name', 'message', 'documentation'}). -record('wsdl:tFault', {anyAttribs, 'name', 'message', 'documentation'}). -record('wsdl:tBinding', {anyAttribs, 'name', 'type', 'documentation', choice, 'operation'}). -record('wsdl:tBindingOperationMessage', {anyAttribs, 'name', 'documentation', choice}). -record('wsdl:tBindingOperationFault', {anyAttribs, 'name', 'documentation', choice}). -record('wsdl:tBindingOperation', {anyAttribs, 'name', 'documentation', choice, 'input', 'output', 'fault'}). -record('wsdl:tService', {anyAttribs, 'name', 'documentation', choice, 'port'}). -record('wsdl:tPort', {anyAttribs, 'name', 'binding', 'documentation', choice}). -record('wsdl:tExtensibilityElement', {anyAttribs, 'wsdl:required'}). yaws-2.0.2/include/yaws.hrl0000664000175000017500000004033012605311412012531 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws.hrl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 16 Jan 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -author('klacke@hyber.org'). %% flags for gconfs -define(GC_TTY_TRACE, 1). -define(GC_DEBUG, 2). -define(GC_COPY_ERRLOG, 4). -define(GC_BACKWARDS_COMPAT_PARSE, 8). -define(GC_LOG_RESOLVE_HOSTNAME, 16). -define(GC_FAIL_ON_BIND_ERR, 32). -define(GC_PICK_FIRST_VIRTHOST_ON_NOMATCH, 64). -define(GC_USE_FDSRV, 128). -define(GC_USE_OLD_SSL, 256). -define(GC_USE_ERLANG_SENDFILE, 512). -define(GC_USE_YAWS_SENDFILE, 1024). -define(GC_DEF, ?GC_FAIL_ON_BIND_ERR). -define(gc_has_tty_trace(GC), ((GC#gconf.flags band ?GC_TTY_TRACE) /= 0)). -define(gc_has_debug(GC), ((GC#gconf.flags band ?GC_DEBUG) /= 0)). -define(gc_has_copy_errlog(GC), ((GC#gconf.flags band ?GC_COPY_ERRLOG) /= 0)). -define(gc_log_has_resolve_hostname(GC), ((GC#gconf.flags band ?GC_LOG_RESOLVE_HOSTNAME) /= 0)). -define(gc_fail_on_bind_err(GC), ((GC#gconf.flags band ?GC_FAIL_ON_BIND_ERR) /= 0)). -define(gc_pick_first_virthost_on_nomatch(GC), ((GC#gconf.flags band ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH) /= 0)). -define(gc_use_old_ssl(GC), ((GC#gconf.flags band ?GC_USE_OLD_SSL) /= 0)). -define(gc_use_erlang_sendfile(GC), ((GC#gconf.flags band ?GC_USE_ERLANG_SENDFILE) /= 0)). -define(gc_use_yaws_sendfile(GC), ((GC#gconf.flags band ?GC_USE_YAWS_SENDFILE) /= 0)). -define(gc_set_tty_trace(GC, Bool), GC#gconf{flags = yaws:flag(GC#gconf.flags,?GC_TTY_TRACE, Bool)}). -define(gc_set_debug(GC, Bool), GC#gconf{flags = yaws:flag(GC#gconf.flags, ?GC_DEBUG, Bool)}). -define(gc_set_copy_errlog(GC, Bool), GC#gconf{flags = yaws:flag(GC#gconf.flags, ?GC_COPY_ERRLOG, Bool)}). -define(gc_log_set_resolve_hostname(GC, Bool), GC#gconf{flags = yaws:flag(GC#gconf.flags, ?GC_LOG_RESOLVE_HOSTNAME, Bool)}). -define(gc_set_fail_on_bind_err(GC, Bool), GC#gconf{flags = yaws:flag(GC#gconf.flags,?GC_FAIL_ON_BIND_ERR,Bool)}). -define(gc_set_pick_first_virthost_on_nomatch(GC, Bool), GC#gconf{flags = yaws:flag(GC#gconf.flags, ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH,Bool)}). -define(gc_set_use_old_ssl(GC, Bool), GC#gconf{flags = yaws:flag(GC#gconf.flags,?GC_USE_OLD_SSL,Bool)}). -define(gc_set_use_erlang_sendfile(GC, Bool), GC#gconf{flags = yaws:flag(GC#gconf.flags,?GC_USE_ERLANG_SENDFILE,Bool)}). -define(gc_set_use_yaws_sendfile(GC, Bool), GC#gconf{flags = yaws:flag(GC#gconf.flags,?GC_USE_YAWS_SENDFILE,Bool)}). %% global conf -record(gconf,{ yaws_dir, % topdir of Yaws installation trace, % false | {true,http} | {true,traffic} flags = ?GC_DEF, % boolean flags logdir, ebin_dir = [], src_dir = [], runmods = [], % runmods for entire server keepalive_timeout = 30000, keepalive_maxuses = nolimit, % nolimit or non negative integer max_num_cached_files = 400, max_num_cached_bytes = 1000000, % 1 MEG max_size_cached_file = 8000, max_connections = nolimit, % max number of TCP connections %% Override default connection handler processes spawn options for %% performance/memory tuning. %% [] | [{fullsweep_after,Number}, {min_heap_size, Size}] %% other options such as monitor, link are ignored. process_options = [], large_file_chunk_size = 10240, mnesia_dir = [], log_wrap_size = 10000000, % wrap logs after 10M cache_refresh_secs = 30, % seconds (auto zero when debug) include_dir = [], % list of inc dirs for .yaws files phpexe = "/usr/bin/php-cgi", % cgi capable php executable yaws, % server string id = "default", % string identifying this instance of yaws enable_soap = false, % start yaws_soap_srv iff true %% a list of %% {{Mod, Func}, WsdlFile, Prefix} | {{Mod, Func}, WsdlFile} %% automatically setup in yaws_soap_srv init. soap_srv_mods = [], ysession_mod = yaws_session_server, % storage module for ysession acceptor_pool_size = 8, % size of acceptor proc pool mime_types_info, % undefined | #mime_types_info{} nslookup_pref = [inet] % [inet | inet6] }). -ifdef(HAVE_SSL_HONOR_CIPHER_ORDER). -define(HONOR_CIPHER_ORDER, true). -else. -define(HONOR_CIPHER_ORDER, undefined). -endif. -ifdef(HAVE_SSL_CLIENT_RENEGOTIATION). -define(SSL_CLIENT_RENEGOTIATION, true). -else. -define(SSL_CLIENT_RENEGOTIATION, undefined). -endif. -ifdef(HAVE_SSL_LOG_ALERT). -define(SSL_LOG_ALERT, {log_alert, false}). -else. -define(SSL_LOG_ALERT, false). -endif. -record(ssl, { keyfile, certfile, verify = 0, fail_if_no_peer_cert, depth = 1, password, cacertfile, dhfile, ciphers, cachetimeout, secure_renegotiate = false, client_renegotiation = ?SSL_CLIENT_RENEGOTIATION, honor_cipher_order = ?HONOR_CIPHER_ORDER, protocol_version }). %% flags for sconfs -define(SC_ACCESS_LOG, 1). -define(SC_AUTH_LOG, 2). -define(SC_ADD_PORT, 4). -define(SC_STATISTICS, 8). -define(SC_TILDE_EXPAND, 16). -define(SC_DIR_LISTINGS, 32). -define(SC_DEFLATE, 64). -define(SC_DIR_ALL_ZIP, 128). -define(SC_DAV, 512). -define(SC_FCGI_TRACE_PROTOCOL, 1024). -define(SC_FCGI_LOG_APP_ERROR, 2048). -define(SC_FORWARD_PROXY, 4096). -define(SC_AUTH_SKIP_DOCROOT, 8192). -define(SC_DEF, ?SC_ACCESS_LOG bor ?SC_ADD_PORT bor ?SC_AUTH_LOG). -define(sc_has_access_log(SC), (((SC)#sconf.flags band ?SC_ACCESS_LOG) /= 0)). -define(sc_has_auth_log(SC), (((SC)#sconf.flags band ?SC_AUTH_LOG) /= 0)). -define(sc_has_add_port(SC), (((SC)#sconf.flags band ?SC_ADD_PORT) /= 0)). -define(sc_has_statistics(SC), (((SC)#sconf.flags band ?SC_STATISTICS) /= 0)). -define(sc_has_tilde_expand(SC), (((SC)#sconf.flags band ?SC_TILDE_EXPAND) /= 0)). -define(sc_has_dir_listings(SC), (((SC)#sconf.flags band ?SC_DIR_LISTINGS) /= 0)). -define(sc_has_deflate(SC), (((SC)#sconf.flags band ?SC_DEFLATE) /= 0)). -define(sc_has_dir_all_zip(SC), (((SC)#sconf.flags band ?SC_DIR_ALL_ZIP) /= 0)). -define(sc_has_dav(SC), (((SC)#sconf.flags band ?SC_DAV) /= 0)). -define(sc_fcgi_trace_protocol(SC), (((SC)#sconf.flags band ?SC_FCGI_TRACE_PROTOCOL) /= 0)). -define(sc_fcgi_log_app_error(SC), (((SC)#sconf.flags band ?SC_FCGI_LOG_APP_ERROR) /= 0)). -define(sc_forward_proxy(SC), (((SC)#sconf.flags band ?SC_FORWARD_PROXY) /= 0)). -define(sc_auth_skip_docroot(SC), (((SC)#sconf.flags band ?SC_AUTH_SKIP_DOCROOT) /= 0)). -define(sc_set_access_log(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_ACCESS_LOG, Bool)}). -define(sc_set_auth_log(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_AUTH_LOG, Bool)}). -define(sc_set_add_port(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_ADD_PORT, Bool)}). -define(sc_set_statistics(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_STATISTICS, Bool)}). -define(sc_set_tilde_expand(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_TILDE_EXPAND, Bool)}). -define(sc_set_dir_listings(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DIR_LISTINGS, Bool)}). -define(sc_set_deflate(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DEFLATE, Bool)}). -define(sc_set_dir_all_zip(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DIR_ALL_ZIP, Bool)}). -define(sc_set_dav(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DAV, Bool)}). -define(sc_set_fcgi_trace_protocol(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_FCGI_TRACE_PROTOCOL, Bool)}). -define(sc_set_fcgi_log_app_error(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_FCGI_LOG_APP_ERROR, Bool)}). -define(sc_set_forward_proxy(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_FORWARD_PROXY, Bool)}). -define(sc_set_auth_skip_docroot(SC, Bool), SC#sconf{flags = yaws:flag(SC#sconf.flags,?SC_AUTH_SKIP_DOCROOT,Bool)}). %% server conf %% we cannot compare sconfs directly due to the ets field in #sconf{} use %% yaws_config:eq_sconfs/2 -record(sconf, { port = 8000, % which port is this server listening to flags = ?SC_DEF, redirect_map=[], % a list of % {Prefix, #url{}, append|noappend} % #url{} can be partially populated rhost, % forced redirect host (+ optional port) rmethod, % forced redirect method docroot, % path to the docs xtra_docroots = [], % if we have additional pseudo docroots listen = [{127,0,0,1}], % bind to this IP, {0,0,0,0} is possible servername = "localhost", % servername is what Host: header is serveralias = [], % Alternate names for this vhost yaws, % server string for this vhost ets, % local store for this server ssl, % undefined | #ssl{} authdirs = [], % [{docroot, [#auth{}]}] partial_post_size = 10240, %% An item in the appmods list can be either of the %% following, this is all due to backwards compat issues. %% 1. an atom - this is the equivalent to {atom, atom} %% 2 . A two tuple {Path, Mod} %% 3 A three tuple {Path, Mod, [ExcludeDir ....]} appmods = [], expires = [], errormod_401 = yaws_outmod, % the default 401 error module errormod_404 = yaws_outmod, % the default 404 error module errormod_crash = yaws_outmod, % use the same module for crashes arg_rewrite_mod = yaws, logger_mod = yaws_log, % access/auth logging module opaque = [], % useful in embedded mode start_mod, % user provided module to be started allowed_scripts = [yaws,php,cgi,fcgi], tilde_allowed_scripts = [], index_files = ["index.yaws", "index.html", "index.php"], revproxy = [], soptions = [{listen_opts, [{backlog, 1024}]}], extra_cgi_vars = [], stats, % raw traffic statistics fcgi_app_server, % FastCGI application server {host,port} php_handler = {cgi, "/usr/bin/php-cgi"}, shaper, deflate_options, % undefined | #deflate{} mime_types_info, % undefined | #mime_types_info{} % if undefined, global config is used dispatch_mod % custom dispatch module }). %% Auth conf - from server conf and .yaws_auth -record(auth, { dir = [], docroot = [], files = [], realm = "", type = "Basic", headers = [], % headers to send on 401 users = [], % list of {User, Password} tuples acl = none, % list of allowed/denies IPs or none mod = [], % authentication module callback outmod = [], % module to handles 401 unauthorized messages pam = false % should we use pam to auth a user }). %% Macro used to list default compressible mime-types -define(DEFAULT_COMPRESSIBLE_MIME_TYPES, [ {"text", all}, {"application", "rtf"}, {"application", "msword"}, {"application", "postscript"}, {"application", "pdf"}, {"application", "x-dvi"}, {"application", "javascript"}, {"application", "x-javascript"} ]). %% Internal record used to initialize a zlib stream for compression -record(deflate, { min_compress_size = nolimit, % nolimit or non negative integer % (in bytes) compression_level = default, % none | default | best_compression | % best_speed | 0..9 window_size = -15, % -15..-9 mem_level = 8, % 1..9 strategy = default, % default | filtered | huffman_only use_gzip_static = false, %% [{Type, undefined|SubType}] | all mime_types = ?DEFAULT_COMPRESSIBLE_MIME_TYPES }). %% Internal record used to set information about mime-types -record(mime_types_info, { mime_types_file, % an absolute filename path types = [], % a map between mime-types and extensions charsets = [], % a map between charsets and extensions default_type = "text/plain", default_charset }). %% this internal record is used and returned by the URL path parser -record(urltype, { type, % error | yaws | regular | directory | forbidden | % appmod finfo, path = [], fullpath = [], % deep list (WHY?) dir = [], % relative dir where the path leads to % flat | unflat need flat for authentication data, % type-specific % e.g: Binary | FileDescriptor | DirListing | undefined deflate, % undefined | Binary | dynamic mime = "text/html", getpath, % as GET'ed by client pathinfo }). %% this record is constructed as we build up the outgoing headers -record(outh, { status, % int status code doclose, % bool chunked, % bool exceedmaxuses=false, % bool, true if hit keep-alive max uses encoding=decide, % decide, identity, deflate contlen, % integer act_contlen, % actual content length for dynamic pages % and the total set of out headers we can have as % actual strings connection, server, location, cache_control, expires, date, allow, last_modified, etag, set_cookie, content_range, content_length, content_type, content_encoding, transfer_encoding, www_authenticate, vary, other % misc other headers }). %% forward and reverse proxy config info -record(proxy_cfg, { prefix, url, intercept_mod }). %% as read by application:get_env() -record(env, { debug, trace, traceoutput, conf, runmod, embedded, id }). %% Typically used in error printouts as in: %% error_logger:format("Err ~p at ~p~n", [Reason, ?stack()]) -define(stack(), try throw(1) catch _:_ -> erlang:get_stacktrace() end). %%% The following is for emacs, do not remove %%% Local Variables: %%% comment-column: 36 %%% End: yaws-2.0.2/include/Makefile.am0000664000175000017500000000037312605311412013076 00000000000000incdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/include dist_inc_DATA = yaws_api.hrl \ yaws_dav.hrl \ yaws.hrl \ yaws_lock.hrl \ yaws_soap.hrl \ soap.hrl \ wsdl11soap12.hrl \ soap-envelope.hrl # Local Variables: # tab-width: 8 # End: yaws-2.0.2/aclocal.m40000664000175000017500000012620412605311444011266 00000000000000# generated automatically by aclocal 1.14.1 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file 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. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file 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. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.14.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.14.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2013 Free Software Foundation, Inc. # # This file 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. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file 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. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file 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. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file 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. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file 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 macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file 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. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file 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. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file 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. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file 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. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file 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. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file 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. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file 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. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/ax_compare_version.m4]) m4_include([m4/colored-echo.m4]) m4_include([m4/erlang.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) yaws-2.0.2/contrib/0000775000175000017500000000000012605311412011134 500000000000000yaws-2.0.2/contrib/yaws_showarg.erl0000664000175000017500000000631712605311412014304 00000000000000-module(yaws_showarg). -export([out/1]). -include("../include/yaws_api.hrl"). f(Fmt, Args) -> io_lib:format(Fmt, Args). out(ARG) -> [ {html, " "}, {ehtml, [ {body,[], [ {h4,[], "ARG information"}, {table,[], [ {thead,[], [ {tr,[], [ {th,[],"record field"},{th,[],"value"} ]} ]}, {tbody,[], [ {tr,[], [ {td,[],"clisock"}, {td,[],f("~p",[ARG#arg.clisock])} ]}, {tr,[], [ {td,[],"client_ip_port"}, {td,[],f("~p",[ARG#arg.client_ip_port])} ]}, {tr,[], [ {td,[],"headers"}, {td,[],f("(see below)",[])} ]}, {tr,[], [ {td,[],"req"}, {td,[],f("~p",[ARG#arg.req])} ]}, {tr,[], [ {td,[],"clidata"}, {td,[],f("~p",[ARG#arg.clidata])} ]}, {tr,[], [ {td,[],"server_path"}, {td,[],f("~p",[ARG#arg.server_path])} ]}, {tr,[], [ {td,[],"querydata"}, {td,[],f("~p",[ARG#arg.querydata])} ]}, {tr,[], [ {td,[],"appmoddata (deprecated)"}, {td,[],f("~p",[ARG#arg.appmoddata])} ]}, {tr,[], [ {td,[],"docroot"}, {td,[],f("~p",[ARG#arg.docroot])} ]}, {tr,[], [ {td,[],"docroot_mount"}, {td,[],f("~p",[ARG#arg.docroot_mount])} ]}, {tr,[], [ {td,[],"fullpath"}, {td,[],f("~p",[ARG#arg.fullpath])} ]}, {tr,[], [ {td,[],"cont"}, {td,[],f("~p",[ARG#arg.cont])} ]}, {tr,[], [ {td,[],"state"}, {td,[],f("~p",[ARG#arg.state])} ]}, {tr,[], [ {td,[],"pid"}, {td,[],f("~p",[ARG#arg.pid])} ]}, {tr,[], [ {td,[],"opaque"}, {td,[],yaws_api:htmlize(f("~p",[ARG#arg.opaque]))} ]}, {tr,[], [ {td,[],"appmod_prepath (deprecated)"}, {td,[],f("~p",[ARG#arg.appmod_prepath])} ]}, {tr,[], [ {td,[],"prepath"}, {td,[],f("~p",[ARG#arg.prepath])} ]}, {tr,[], [ {td,[],"pathinfo"}, {td,[],f("~p",[ARG#arg.pathinfo])} ]} ]} ]}, {h4,[], "headers"}, {pre,[], f("~p",[yaws_api:reformat_header(ARG#arg.headers)])}, {hr,[],[]}, {h4,[], "raw ARG"}, {pre,[], yaws_api:htmlize(f("~p", [ARG]))}, {hr,[],[]} ]} ] }, {html, " "} ]. yaws-2.0.2/contrib/benchmarks/0000775000175000017500000000000012605311412013251 500000000000000yaws-2.0.2/contrib/benchmarks/multipart_bm.erl0000664000175000017500000000272512605311412016402 00000000000000-module(multipart_bm). -include("../../include/yaws_api.hrl"). -export([benchmarks/0]). -export([long_msg/1]). benchmarks() -> {100, [long_msg]}. long_msg(Iter) -> Sep = make_rand_bin(32), Body = binary:copy(make_rand_bin(10240), 100), Msg = list_to_binary(["--", Sep, "\r\n", "Content-Disposition: form-data; name=\"abc123\"; ", "filename=\"abc123\"\r\n", "Content-Type: text/plain\r\n", "Test-Header: sampledata\r\n\r\n", Body, "\r\n--",Sep,"--\r\n" ]), long_msg(Iter, mk_arg(Msg, Sep), Body). long_msg(0, _Msg, _Body) -> ok; long_msg(Iter, Msg, Body) -> {result, Res} = yaws_api:parse_multipart_post(Msg, [binary]), Body = proplists:get_value(body, Res), %%io:format("~p~n", [Res]), long_msg(Iter - 1, Msg, Body). make_rand_bin(Length) -> State = rand:seed_s(exs64), make_rand_bin(Length, State, <<>>). make_rand_bin(0, _State, Acc) -> Acc; make_rand_bin(Length, State, Acc) -> {Rand, State1} = rand:uniform_s($z - $a, State), make_rand_bin(Length - 1, State1, <>). mk_arg(Data, Sep) -> ContentType = binary_to_list(<<"multipart/form-data; boundary=", Sep/binary>>), Req = #http_request{method = 'POST'}, Headers = #headers{content_type = ContentType}, #arg{headers = Headers, req = Req, clidata = Data}. yaws-2.0.2/contrib/benchmarks/all.erl0000664000175000017500000000703512605311412014452 00000000000000%% ``The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved via the world wide web at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB. %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings %% AB. All Rights Reserved.'' %% %% $Id$ %% -module(all). %% User interface -export([run/0]). %% Interna constants -define(NORMAL, 0). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Interface %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%--------------------------------------------------------------------------- %% run() -> _ %% %% Runs all benchmark modules in the current directory on all erlang %% installations specified by releases/0 %%--------------------------------------------------------------------------- run() -> %% Delete previous intermediate test result files. lists:foreach(fun(F) -> file:delete(F) end, filelib:wildcard("*.bmres")), lists:foreach(fun run/1, releases()). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Internal functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%--------------------------------------------------------------------------- %% run(Release) -> _ %% Release = string() - Erlang release %% Help functions to run/0 %%--------------------------------------------------------------------------- run(Release) -> command(Release ++ " -noshell -compile bench -s erlang halt"), command(Release ++ " -noshell -s bench run -s erlang halt"). %%--------------------------------------------------------------------------- %% command(Command) -> _ %% Command = string() - is the name and arguments of the external %% program which will be run %%--------------------------------------------------------------------------- command(Command) -> io:format("~s\n", [Command]), % Progress info to user Port = open_port({spawn,Command}, [exit_status, in]), print_output(Port). %%--------------------------------------------------------------------------- %% print_output(Port) -> _ %% Port = port() %% Print data from the port i.e. output from external program, %% on standard out. %%--------------------------------------------------------------------------- print_output(Port) -> receive {Port, {data,Bytes}} -> io:put_chars(Bytes), print_output(Port); {Port, {exit_status, ?NORMAL}} -> ok end. %%--------------------------------------------------------------------------- %% run() -> Releases %% Releases = [Release |_] %% Release = string() - Erlang release %% Defines which erlang releases to run on %% --- Change this function to reflect your own erlang installations --- %%--------------------------------------------------------------------------- releases() -> ["/usr/local/otp/releases/otp_beam_sunos5_r7b01_patched/bin/erl", "/usr/local/otp/releases/otp_beam_sunos5_r8b_patched/bin/erl"]. yaws-2.0.2/contrib/benchmarks/README0000664000175000017500000000112112605311412014044 00000000000000Benchmarks for yaws_server as discussed in the 'Benchmarking' section of the OTP 'Efficiency Guide' In an erl shell run from the benchmarks folder: -------------------------- 1> c(bench). {ok,bench} 2> bench:run(). Compiling conc_path_bm.erl... Compiling bench.erl... Compiling all.erl... Running conc_path_bm: conc_path_orig conc_path_tail conc_path_lappend conc_path_lflatten conc_path_lconcat ok -------------------------- This should generate an index.html file in this folder showing the relative performance. See conc_path_bm.erl for a trivial example that may be useful as a base. yaws-2.0.2/contrib/benchmarks/conc_path_bm.erl0000664000175000017500000001016012605311412016307 00000000000000%% %% See '8.5 Benchmarking' under 'Efficiency Guide' in the OTP documentation. %% % % This particular benchmark was assembled to learn about Erlang benchmarking on a simple case and to % satisfy my curiosity as to why the yaws_server:conc_path/1 function was used instead of one of the % 'lists' functions such as lists:append, and why conc_path isn't tail-recursive. % % Note that I'm not suggesting that conc_path is necessarily worth of particular attention regarding performance! % (though it may be.. ) % Applying this sort of benchmark to such small parts of Yaws at this stage (v 1.68) could quite reasonably be classed % as 'premature optimization' I think ;) % Proper profiling would need to be done to determine what code paths are actually performance sensitive and worthy % of attention. % -module(conc_path_bm). -author('julian@precisium.com.au'). -include("bench.hrl"). -include("../../include/yaws_api.hrl"). -include("../../src/yaws_debug.hrl"). -include("../../include/yaws.hrl"). -export([benchmarks/0]). -export([conc_path_orig/1,conc_path_tweaked/1, conc_path_tail/1, conc_path_lappend/1, conc_path_lflatten/1, conc_path_lconcat/1]). benchmarks() -> {20000, [conc_path_orig, conc_path_tweaked, conc_path_tail, conc_path_lappend, conc_path_lflatten, conc_path_lconcat]}. %-------------------------------------- % original conc_path from yaws_server.erl %-------------------------------------- conc_path_orig(Iter) -> do_conc_path_orig(Iter, getData()). do_conc_path_orig(0, _Path) -> ok; do_conc_path_orig(Iter, Path) -> ?rep20(conc_path(Path)), do_conc_path_orig(Iter-1, Path). %-------------------------------------- % slightly tweaked conc_path from yaws_server.erl %-------------------------------------- conc_path_tweaked(Iter) -> do_conc_path_tweaked(Iter, getData()). do_conc_path_tweaked(0, _Path) -> ok; do_conc_path_tweaked(Iter, Path) -> ?rep20(conc_path2(Path)), do_conc_path_tweaked(Iter-1, Path). %-------------------------------------- % tail recursive version of conc_path %-------------------------------------- conc_path_tail(Iter) -> do_conc_path_tail(Iter, getData()). do_conc_path_tail(0, _Path) -> ok; do_conc_path_tail(Iter, Path) -> ?rep20(conc_path_tailrecursive(Path)), do_conc_path_tail(Iter-1, Path). %-------------------------------------- % lists:flatten %-------------------------------------- conc_path_lflatten(Iter) -> do_conc_path_lflatten(Iter, getData()). do_conc_path_lflatten(0, _Path) -> ok; do_conc_path_lflatten(Iter, Path) -> ?rep20(lists:flatten(Path)), do_conc_path_lflatten(Iter-1, Path). %-------------------------------------- % lists:concat %-------------------------------------- conc_path_lconcat(Iter) -> do_conc_path_lconcat(Iter, getData()). do_conc_path_lconcat(0, _Path) -> ok; do_conc_path_lconcat(Iter, Path) -> ?rep20(lists:concat(Path)), do_conc_path_lconcat(Iter-1, Path). %-------------------------------------- % lists:append %-------------------------------------- conc_path_lappend(Iter) -> do_conc_path_lappend(Iter, getData()). do_conc_path_lappend(0, _Path) -> ok; do_conc_path_lappend(Iter, Path) -> ?rep20(lists:append(Path)), do_conc_path_lappend(Iter-1, Path). %-------------------------------------- % Which function performs better, unsuprisingly, varies a bit depending on the data. %-------------------------------------- getData() -> ["usr/", "local/", "www/", "some.doc"]. getData2() -> ["/usr/", "local/", "etc"]. getData3() -> ["usr/", "local", "/", "etc" , "/", "www/somewhere strange", "/", "SomeUserOrSomething/blah/", "blah/"]. getData4() -> ["/usr/", "local/"]. getData5() -> ["/usr/"]. %-------------------------------------- conc_path([]) -> []; conc_path([H|T]) -> H ++ conc_path(T). conc_path2([]) -> []; conc_path2([H|[]]) -> H; conc_path2([H|T]) -> H ++ conc_path2(T). conc_path_tailrecursive([]) -> []; conc_path_tailrecursive([H|T]) -> c2(T,H). c2([],Acc) -> Acc; c2([H|[]],Acc) -> H ++ Acc; c2([H|T],Acc) -> c2(T,Acc ++ H). yaws-2.0.2/contrib/benchmarks/bench.erl0000664000175000017500000004630612605311412014765 00000000000000%% ``The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved via the world wide web at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB. %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings %% AB. All Rights Reserved.'' %% %% $Id$ %% -module(bench). %% User interface -export([run/0]). %% Exported to be used in spawn -export([measure/4]). %% Internal constants -define(MAX, 999999999999999). -define(RANGE_MAX, 16#7ffffff). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Interface %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%--------------------------------------------------------------------------- %% run() -> _ %% %% Compiles and runs all benchmarks in the current directory, %% and creates a report %%--------------------------------------------------------------------------- run() -> run(compiler_options()). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Generic Benchmark functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%--------------------------------------------------------------------------- %% compiler_options() -> OptionsList %% OptionsList = list() - See Erlang/OTP module compile %%--------------------------------------------------------------------------- compiler_options() -> [report_errors, report_warnings]. %%--------------------------------------------------------------------------- %% run(OptionsList) -> %% OptionsList = list() - See Erlang/OTP module compile %% %% Help function to run/0. %%--------------------------------------------------------------------------- run(OptionsList) -> Bms = compile_benchmarks(OptionsList), run_benchmarks(Bms), report(). %%--------------------------------------------------------------------------- %% compile_benchmarks(OptionsList) -> [BmInfo| _] %% OptionsList = list() - See Erlang/OTP module compile %% BmInfo = {Module, Iterations, [BmFunctionName| _]} %% Module = atom() %% Iterations = integer() %% BmFunctionName = atom() %% %% Compiles all benchmark modules in the current directory and %% returns info about the benchmarks. %%--------------------------------------------------------------------------- compile_benchmarks(OptionsList) -> {ok, FilesInCurrentDir} = file:list_dir("."), ErlFiles = [ErlFile || ErlFile <- lists:sort(FilesInCurrentDir), lists:suffix(".erl", ErlFile)], lists:foldr(fun(File, BmInfoAcc) -> case lists:suffix("_bm.erl", File) of true -> BmInfo = bm_compile(File, OptionsList), [BmInfo | BmInfoAcc]; false -> just_compile(File, OptionsList), BmInfoAcc end end, [], ErlFiles). %%--------------------------------------------------------------------------- %% just_compile(FileName, OptionsList) -> ok %% FileName = string() %% OptionsList = list() - See Erlang/OTP module compile %% %% Compiles a support module. %%--------------------------------------------------------------------------- just_compile(FileName, OptionsList) -> io:format("Compiling ~s...\n", [FileName]), % Progress info to user case c:c(FileName, OptionsList) of {ok, _Mod} -> ok; %% If compilation fails there is no point in trying to continue error -> Reason = lists:flatten( io_lib:format("Could not compile file ~s", [FileName])), exit(self(), Reason) end. %%--------------------------------------------------------------------------- %% bm_compile(FileName, OptionsList) -> BmInfo %% FileName = string() %% OptionsList = list() - See Erlang/OTP module compile %% BmInfo = {Module, Iterations, [BmFunctionName| _]} %% Iterations = integer() %% Module = atom() %% BmFunctionName = atom() %% %% Compiles the benchmark module implemented in and returns %% information about the benchmark tests. %%--------------------------------------------------------------------------- bm_compile(FileName, OptionsList) -> io:format("Compiling ~s...\n", [FileName]), % Progress info to user case c:c(FileName, OptionsList) of {ok, Mod} -> bm_cases(Mod); %% If compilation fails there is no point in trying to continue error -> Reason = lists:flatten( io_lib:format("Could not compile file ~s", [FileName])), exit(self(), Reason) end. %%--------------------------------------------------------------------------- %% bm_cases(Module) -> {Module, Iter, [BmFunctionName |_]} %% Module = atom() %% Iter = integer() %% BmFunctionName = atom() %% %% Fetches the number of iterations and the names of the benchmark %% functions for the module . %%--------------------------------------------------------------------------- bm_cases(Module) -> case catch Module:benchmarks() of {Iter, BmList} when is_integer(Iter), is_list(BmList) -> {Module, Iter, BmList}; %% The benchmark is incorrect implemented there is no point in %% trying to continue Other -> Reason = lists:flatten( io_lib:format("Incorrect return value: ~p " "from ~p:benchmarks()", [Other, Module])), exit(self(), Reason) end. %%--------------------------------------------------------------------------- %% run_benchmarks(Bms) -> %% Bms = [{Module, Iter, [BmFunctionName |_]} | _] %% Module = atom() %% Iter = integer() %% BmFunctionName = atom() %% %% Runs all the benchmark tests described in . %%--------------------------------------------------------------------------- run_benchmarks(Bms) -> Ver = erlang:system_info(version), Machine = erlang:system_info(machine), SysInfo = {Ver,Machine}, Res = [bms_run(Mod, Tests, Iter, SysInfo) || {Mod,Iter,Tests} <- Bms], %% Create an intermediate file that is later used to generate a bench %% mark report. Name = Ver ++ [$.|Machine] ++ ".bmres", {ok, IntermediatFile} = file:open(Name, [write]), %% Create mark that identifies version of the benchmark modules io:format(IntermediatFile, "~p.\n", [erlang:phash(Bms, ?RANGE_MAX)]), io:format(IntermediatFile, "~p.\n", [Res]), file:close(IntermediatFile). %%--------------------------------------------------------------------------- %% bms_run(Module, BmTests, Iter, Info) -> %% Module = atom(), %% BmTests = [BmFunctionName|_], %% BmFunctionName = atom() %% Iter = integer(), %% SysInfo = {Ver, Machine} %% Ver = string() %% Machine = string() %% %% Runs all benchmark tests in module . %%--------------------------------------------------------------------------- bms_run(Module, BmTests, Iter, SysInfo) -> io:format("Running ~s:", [Module]), % Progress info to user Res = {Module,{SysInfo,[{Bm, bm_run(Module, Bm, Iter)} || Bm <- BmTests]}}, io:nl(), Res. %%--------------------------------------------------------------------------- %% bm_run(Module, BmTest, Iter) -> Elapsed %% Module = atom(), %% BmTest = atom(), %% Iter = integer() %% Elapsed = integer() - elapsed time in milliseconds. %% %% Runs the benchmark Module:BmTest(Iter) %%--------------------------------------------------------------------------- bm_run(Module, BmTest, Iter) -> io:format(" ~s", [BmTest]), % Progress info to user spawn_link(?MODULE, measure, [self(), Module, BmTest, Iter]), receive {Elapsed, ok} -> Elapsed; {_Elapsed, Fault} -> io:nl(), Reason = lists:flatten( io_lib:format("~w", [Fault])), exit(self(), Reason) end. %%--------------------------------------------------------------------------- %% measure(Parent, Module, BmTest, Iter) -> _ %% Parent = pid(), %% Module = atom(), %% BmTest = atom(), %% Iter = integer() %% %% Measures the time it take to execute Module:Bm(Iter) %% and send the result to . %%--------------------------------------------------------------------------- measure(Parent, Module, BmTest, Iter) -> statistics(runtime), Res = (catch apply(Module, BmTest, [Iter])), {_TotalRunTime, TimeSinceLastCall} = statistics(runtime), Parent ! {TimeSinceLastCall, Res}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Report functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%--------------------------------------------------------------------------- %% report() -> _ %% %% Creates a report of the bench marking test that appeals to a human. %% Currently this means creating a html-file. (Other formats could be added) %%--------------------------------------------------------------------------- report() -> {ok, AllFiles} = file:list_dir("."), BmResultFiles = [File || File <- AllFiles, lists:suffix(".bmres", File)], Results = fetch_bmres_data(BmResultFiles), create_report(Results). %%--------------------------------------------------------------------------- %% fetch_bmres_data(BmResultFiles) -> Results %% BmResultFiles = [FileName | _] %% FileName = string() %% Results = [[{Bm, Res} | _]] %% Bm = atom() - Name of benchmark module %% Res = [{VersionInfo, [{Test, Time} | _]}] %% VersionInfo = {Ver, Machine} %% Ver = string() %% Machine = string() %% Test = atom() %% Time = integer() %% %% Reads result data from intermediate files %%--------------------------------------------------------------------------- fetch_bmres_data(BmResultFiles) -> fetch_bmres_data(BmResultFiles, [], undefined). %%--------------------------------------------------------------------------- %% fetch_bmres_data(BmResultFiles, AccResData, Check) -> Results %% BmResultFiles = [FileName | _] %% FileName = string() %% AccResData = see Results fetch_bmres_data/1 %% Check = integer() | undefined (first time) %% %% Help function to fetch_bmres_data/1 %%--------------------------------------------------------------------------- fetch_bmres_data([], AccResData, _Check) -> AccResData; fetch_bmres_data([Name | BmResultFiles], AccResData, Check) -> {DataList, NewCheck} = read_bmres_file(Name, Check), fetch_bmres_data(BmResultFiles, [DataList| AccResData], NewCheck). %%--------------------------------------------------------------------------- %% read_bmres_file(Name, Check) -> %% Name = string() %% Check = integer() | undefined %% %% Reads the data from the result files. Checks that all result %% files where created with the same set of tests. %%--------------------------------------------------------------------------- read_bmres_file(Name, Check) -> case file:consult(Name) of {ok, [Check1, List]} when Check =:= undefined, is_integer(Check1) -> {List, Check1}; {ok, [Check, List]} when is_integer(Check) -> {List, Check}; {ok, [Check1, _List]} when is_integer(Check1) -> Reason = lists:flatten( io_lib:format("Different test setup, remove old setup " "result by removing *.bmres files and " "try again", [])), exit(self(), Reason); {error, Reason} when is_atom(Reason) -> exit(self(), Reason); {error, Reason} -> exit(self(), file:format_error(Reason)) end. %%--------------------------------------------------------------------------- %% create_report(Results) -> %% Results = see Results fetch_bmres_data/1 %% %% Organizes so it will be right for create_html_report/1 %% i.e. group results for the same benchmark test, run on different versions %% of erlang. %%--------------------------------------------------------------------------- create_report(Results) -> Dictionary = lists:foldl(fun(BmResultList, Dict0) -> lists:foldl(fun({Bm, VerResult}, Dict1) -> dict:append(Bm, VerResult, Dict1) end,Dict0, BmResultList) end, dict:new(), Results), create_html_report(dict:to_list(Dictionary)). %%--------------------------------------------------------------------------- %% create_html_report(ResultList) -> _ %% ResultList = [{Bm, Res} | _] %% Bm = atom() - Name of benchmark module %% Res = [{VersionInfo, [{Test, Time} | _]} | _] %% VersionInfo = {Ver, Machine} %% Ver = string() %% Machine = string() %% Test = atom() %% Time = integer() %% %% Writes the result to an html-file %%--------------------------------------------------------------------------- create_html_report(ResultList) -> {ok, OutputFile} = file:open("index.html", [write]), %% Create the begining of the result html-file. Head = Title = "Benchmark Results", io:put_chars(OutputFile, "\n"), io:put_chars(OutputFile, "\n"), io:format(OutputFile, "~s\n", [Title]), io:put_chars(OutputFile, "\n"), io:put_chars(OutputFile, "\n"), io:format(OutputFile, "

~s

\n", [Head]), io:fwrite("~nResultlist: ~p~n",[ResultList]), %% Add the result tables lists:foreach(fun(Element) -> create_html_table(OutputFile, Element) end, ResultList), %% Put in the end-html tags io:put_chars(OutputFile, "\n"), io:put_chars(OutputFile, "\n"), file:close(OutputFile). %%--------------------------------------------------------------------------- %% create_html_table(File, {Bm, Res}) -> _ %% File = file() - html file to write data to. %% Bm = atom() - Name of benchmark module %% Res = [{VersionInfo, [{Test, Time} | _]}] %% VersionInfo = {Ver, Machine} %% Ver = string() %% Machine = string() %% Test = atom() %% Time = integer() %% %% Creates a html table that displays the result of the benchmark . %%--------------------------------------------------------------------------- create_html_table(File, {Bm, Res}) -> {MinTime, Order} = min_time_and_sort(Res), io:format(File, "

~s

\n" , [Bm]), %% Fun that calculates relative measure values and puts them in %% a dictionary RelativeMesureFun = fun({TestName, Time}, Dict1) -> dict:append(TestName, Time/MinTime, Dict1) end, %% For all erlang versions that the benchmark tests has been run, %% calculate the relative measure values and put them in a dictionary. ResultDict = lists:foldl(fun({_VerInfo, Bms}, Dict0) -> lists:foldl(RelativeMesureFun, Dict0, Bms) end, dict:new(), Res), %% Create the table and its headings io:put_chars(File, "" "
\n"), io:put_chars(File, "\n"), io:put_chars(File, ""), io:put_chars(File, ""), Heads = table_headers(Res), lists:foreach(fun({Ver,Machine}) -> io:format(File, "", [Ver,Machine]) end, Heads), io:put_chars(File, "\n"), %% Create table rows lists:foreach(fun(Name) -> create_html_row(File, Name, ResultDict) end, Order), %% Tabel end-tags io:put_chars(File, "
Test~s
~s
\n"), %% Create link to benchmark source code io:format(File, "

Source for ~s.erl\n", [Bm,Bm]). %%--------------------------------------------------------------------------- %% create_html_row(File, Name, Dict) -> _ %% File = file() - html file to write data to. %% Name = atom() - Name of benchmark test %% Dict = dict() - Dictonary where the relative time measures for %% the test can be found. %% %% Creates an actual html table-row. %%--------------------------------------------------------------------------- create_html_row(File, Name, Dict) -> ReletiveTimes = dict:fetch(Name, Dict), io:put_chars(File, "\n"), io:format(File, "~s", [Name]), lists:foreach(fun(Time) -> io:format(File, "~-8.2f", [Time]) end, ReletiveTimes), io:put_chars(File, "\n"). %%--------------------------------------------------------------------------- %% min_time_and_sort(ResultList) -> {MinTime, Order} %% ResultList = [{VersionInfo, [{Test, Time} | _]}] %% MinTime = integer() - The execution time of the fastes test %% Order = [BmFunctionName|_] - the order of the testcases in %% increasing execution time. %% BmFunctionName = atom() %%--------------------------------------------------------------------------- min_time_and_sort(ResultList) -> %% Use the results from the run on the highest version %% of Erlang as norm. {_, TestRes} = lists:foldl(fun ({{Ver, _}, ResList}, {CurrentVer, _}) when Ver > CurrentVer -> {Ver, ResList}; (_, VerAndRes) -> VerAndRes end, {"0", []}, ResultList), {lists:foldl(fun ({_, Time0}, Min1) when Time0 < Min1 -> Time0; (_, Min1) -> Min1 end, ?MAX, TestRes), [Name || {Name, _} <- lists:keysort(2, TestRes)]}. %%--------------------------------------------------------------------------- %% table_headers(VerResultList) -> SysInfo %% VerResultList = [{{Ver, Machine},[{BmFunctionName, Time}]} | _] %% Ver = string() %% Machine = string() %% BmFunctionName = atom() %% Time = integer() %% SysInfo = {Ver, Machine} %%--------------------------------------------------------------------------- table_headers(VerResultList) -> [SysInfo || {SysInfo, _} <- VerResultList]. yaws-2.0.2/contrib/benchmarks/bench.hrl0000664000175000017500000000172312605311412014762 00000000000000%% ``The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved via the world wide web at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB. %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings %% AB. All Rights Reserved.'' %% %% $Id$ %% -define(rep5(X), X, X, X, X, X). -define(rep10(X), ?rep5(X), ?rep5(X)). -define(rep20(X), ?rep10(X), ?rep10(X)). -define(rep40(X), ?rep20(X), ?rep20(X)). -define(rep80(X), ?rep40(X), ?rep40(X)). yaws-2.0.2/contrib/yaws_mnesia_session.erl0000664000175000017500000000636112605311412015650 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_mnesia_session.erl %%% Author : Nicolas Thauvin %%% Purpose : mnesia storage callbacks for yaws_session_server %%%---------------------------------------------------------------------- %% Warning !!! %% This module may init mnesia in a way that is not suitable for your %% application ! %% Quick steps: %% 1) Compile this module %% 2) Drop the .beam in your code path %% 3) Run Yaws with the -module (yaws_mnesia_session). -export ([init_backend/1, stop_backend/0]). -export ([list/0, insert/1, lookup/1, delete/1]). -export ([traverse/1, cleanup/0]). -define(TABLE, ysession). init_backend(Fields) -> case net_kernel:get_net_ticktime() of ignored -> Message = "mnesia backend needs distribution (a node name)", Error = {?MODULE, Message}, error_logger:error_msg("~p~n", [Error]), exit (Error); _ -> ok end, case catch mnesia:table_info(schema, where_to_write) of Nodes when is_list(Nodes) -> case catch mnesia:table_info(?TABLE, where_to_write) of {'EXIT', {aborted, {no_exists, ?TABLE, where_to_write}}} -> Nodes = mnesia:system_info(running_db_nodes), Options = [{disc_copies, Nodes}, {type, set}, {attributes, Fields}], {atomic, ok} = mnesia: create_table (?TABLE, Options), ok; List when is_list (List) -> ok = mnesia:wait_for_tables([?TABLE], 60000) end; {'EXIT',{aborted,{no_exists,schema,where_to_write}}} -> application:stop(mnesia), mnesia:create_schema([node()]), ok = application:start(mnesia), init_backend(Fields) end. stop_backend() -> ok. insert(Session) -> Fun = fun () -> mnesia:write(Session) end, {atomic, ok} = mnesia:transaction(Fun), true. lookup(Key) -> Fun = fun () -> mnesia:read(?TABLE, Key) end, {atomic, Result} = mnesia:transaction(Fun), Result. delete(Key) -> Fun = fun () -> mnesia:delete({?TABLE, Key}) end, {atomic, Result} = mnesia:transaction(Fun), Result. list() -> Fold = fun (Session, Acc) -> [Session | Acc] end, Fun = fun () -> mnesia:foldl(Fold, [], ?TABLE) end, {atomic, Result} = mnesia:transaction(Fun), Result. cleanup() -> mnesia:clear_table(?TABLE). traverse(Gnow) -> Fun = fun() -> tr_traverse(Gnow) end, {atomic, Result} = mnesia:transaction(Fun), Result. tr_traverse(Gnow) -> tr_traverse(Gnow, mnesia:first(?TABLE)). tr_traverse(_N, '$end_of_table') -> ok; tr_traverse(N, Key) -> case mnesia:read(?TABLE, Key) of [Y] -> case yaws_session_server:has_timedout(Y, N) of false -> tr_traverse(N, mnesia:next(?TABLE, Key)); true -> yaws_session_server:report_timedout_sess(Y), Next = mnesia:next(?TABLE, Key), mnesia:delete({?TABLE, Key}), tr_traverse(N, Next) end; [] -> tr_traverse(N, mnesia:next(?MODULE, Key)) end. yaws-2.0.2/contrib/ymnesia.erl0000664000175000017500000002202712605311412013230 00000000000000%%%------------------------------------------------------------------- %%% Created : 14 Oct 2005 by Torbjorn Tornkvist %%% Desc. : A naive Mnesia table viewer Yaws-app interface. %%% %%% @author Torbjorn Tornkvist %%% %%% @doc Ymnesia is a Yaws appmod to view Mnesia tables. %%% Add ymnesia as an appmod to your Yaws configuration. %%% Point your browser to: <url>/ymnesia %%% %%%

    %%%
  • You can search on arbitrary Erlang terms. %%%
    (atoms need to be single-quoted)
  • %%%
  • The checkbox control if the attribute should be shown in %%% the result.
    No checkbox means: show all attributes.
  • %%%
%%% %%%

%%% To test it, add it as an appmod to you Yaws configuration, e.g: %%% %%% appmods = [{"showdb", ymnesia}} %%% %%% then point your browser to: http://<host>/showdb/ %%%

%%% @end %%% %%%------------------------------------------------------------------- -module(ymnesia). -export([out/1]). -import(lists, [map/2, foldl/3, reverse/1]). -include("../include/yaws_api.hrl"). -define(elog(X,Y), error_logger:info_msg("*elog ~p:~p: " X, [?MODULE, ?LINE | Y])). %%% Possible to call mnesia in another way -define(MNESIA(Mod, Args), apply(mnesia, Mod, Args)). %%-define(MNESIA(Mod, Args), fdapi:call_in_master(mnesia, Mod, Args)). %%% @private out(A) -> %%?elog("Inside Ymnesia~n", []), case string:tokens(A#arg.appmoddata, "/.") of ["table" | _] -> case is_post(A) of true -> L = yaws_api:parse_post(A), {Cbox, Rest} = extract_cbox(L), Name = lk("tablename", Rest), Ls = select_fields(Rest), Sp = (catch select_pattern(Name, Ls)), case catch table(Cbox, Sp, l2a(Name)) of {'EXIT', Reason} -> ?elog("Error , reason: ~p~n", [Reason]), error_page("table not found: "++Name); Else -> Else end; false -> return_top_page() end; _ -> return_top_page() end. %%% Get the fields to be part of the select select_fields([{"tablename",_}|T]) -> select_fields(T); select_fields([{_,undefined}|T]) -> select_fields(T); select_fields([H|T]) -> [H|select_fields(T)]; select_fields([]) -> []. select_pattern(Name, Ls) -> Wp = ?MNESIA(table_info, [l2a(Name), wild_pattern]), mk_select_pattern(map(fun(A) -> a2l(A) end,get_attributes(l2a(Name))), Ls, Wp, 2). mk_select_pattern([A|As], [{A,V}|T], Wp, N) -> mk_select_pattern(As, T, setelement(N, Wp, be_smart(V)), N+1); mk_select_pattern([_|As], L, Wp, N) -> mk_select_pattern(As, L, Wp, N+1); mk_select_pattern([], [], Wp, _) -> Wp. %%% Try to be intelligent and convert the Key to the datatype that %%% could be expected. Note: atom is anything between single quotes. be_smart([$'|T]) -> l2a(eat_until($', T)); be_smart([$[|_] = L) -> str2term(L); be_smart([${|_] = L) -> str2term(L); be_smart(L) -> case be_smart(L, false) of integer -> list_to_integer(L); float -> list_to_float(L); _ -> L end. eat_until(H, [H|_]) -> []; eat_until(X, [H|T]) -> [H|eat_until(X,T)]. be_smart([H|T], false) when H>$0, H=<$9 -> be_smart(T, integer); be_smart([H|T], integer) when H>$0, H=<$9 -> be_smart(T, integer); be_smart([H|T], integer) when H>$. -> be_smart(T, float); be_smart([_|T], _) -> be_smart(T, list); be_smart([], Type) -> Type. return_top_page() -> {ehtml, [{head, [], [meta() ++ style()]}, {body, [], mk_table_tab()}]}. is_post(A) -> case (A#arg.req)#http_request.method of 'GET' -> false; 'POST' -> true end. meta() -> [{pre_html, ""}]. style() -> [{style, [{type, "text/css"}], [{pre_html, ["table {border-collapse: collapse; border: solid black 1px;}\n" "p {padding: 5px; font-weight: bold;}\n" "input[type=text] {vertical-align: bottom; width: 100%; font-size: 80%;}\n" "input[type=checkbox] {vertical-align: top; font-size: 80%;}\n" "span.attribute {vertical-align: top; font-size: 80%;}\n" "th {padding: 5px; border: solid black 1px;}\n" "td {padding: 5px; border: solid black 1px;}\n" ]}]}]. %%% Build the result page. table(Cbox, Sp, Table) when is_atom(Table) -> case catch ?MNESIA(table_info, [Table, attributes]) of Headers when is_list(Headers) -> Vp = view_pattern(Cbox, map(fun(X) -> a2l(X) end, Headers)), {Q, Result} = do_query(Sp), {ehtml, [{head, [], [meta() ++ style()]}, {body, [], [{'div', [], {p, [], "Query: "++Q}}, {'div', [], {p, [], "Table: "++a2l(Table)}} | mk_tab(Vp, Headers, t2l(Result))]}]}; Else -> Else end. %%% Create a pattern denoting which fields to show in the result. view_pattern(Cs, L) -> view_pattern(Cs, L, 1). view_pattern([Cbox|Cs], [Cbox|T], N) -> [N | view_pattern(Cs, T, N+1)]; view_pattern(Cs, [_|T], N) -> view_pattern(Cs, T, N+1); view_pattern([], [], _) -> []. %%% Create a table of: Table | Table-attribute-1 | ... | Table-attribute-N %%% where each table is a Form mk_table_tab() -> Rows = get_tables(), [{'div', [], [{table, [], map(fun(Row) -> {tr, [], {form, [{action, "table.yaws"}, {method, "post"}, {name, Row}], [{td, [], sublnk(a2l(Row))} | mk_input_fields(Row)]}} end, Rows)}]}]. %%% Create each table cell; consisting of the attribute name and an input field. mk_input_fields(Table) -> As = get_attributes(Table), Max = max_noof_attrs(), map(fun(0) -> {td, [], []}; (Attribute) -> A = a2l(Attribute), {td, [], [{input, [{type, "checkbox"}, {name, "cbox_"++A}]}, {span, [{class, "attribute"}], A}, {input, [{type, "text"}, {name, A}]}]} end, As ++ lists:duplicate(Max-length(As), 0)). extract_cbox(L) -> extract_cbox(L, [], []). extract_cbox([{"cbox_"++Cbox,_}|T], Cs, Rs) -> extract_cbox(T, [Cbox|Cs], Rs); extract_cbox([H|T], Cs, Rs) -> extract_cbox(T, Cs, [H|Rs]); extract_cbox([], Cs, Rs) -> {reverse(Cs), reverse(Rs)}. %%% Build the result table. mk_tab(Vp, Headers, Rows) -> [{'div', [], [{table, [], [{tr, [], [{th, [], a2l(X)} || X <- vp(Vp,Headers)]} | map(fun(Row) -> {tr, [], [{td, [], massage(W)} || W <- vp(Vp,Row)]} end, Rows)]}]}]. %%% Match the view pattern to select which entries to let through. vp([], L) -> L; vp(Vp, L) -> vp(Vp, L, 1). vp([N|Vp], [H|T], N) -> [H|vp(Vp, T, N+1)]; vp(Vp, [_|T], N) -> vp(Vp, T, N+1); vp([], [], _) -> []. %%% Create a link that submit the form: onclick sublnk(E) -> {a, [{href, "#"}, {onclick, E++".submit();"}], [E, {input, [{type, "hidden"}, {name, "tablename"}, {value, E}]}]}. massage(W) -> lists:flatten(io_lib:format("~p",[W])). do_query(Sp) -> {lists:flatten(io_lib:format("mnesia:match_object(~p)", [Sp])), lists:keysort(2, ?MNESIA(dirty_match_object, [Sp]))}. error_page(Msg) -> {html, [Msg]}. get_tables() -> ?MNESIA(system_info, [tables]) -- [schema]. get_attributes(Table) -> ?MNESIA(table_info, [Table, attributes]). max_noof_attrs() -> foldl(fun(Table, Max) -> erlang:max(length(get_attributes(Table)), Max) end, 0, get_tables()). a2l(A) when is_atom(A) -> atom_to_list(A); a2l(L) when is_list(L) -> L. l2a(L) when is_list(L) -> list_to_atom(L); l2a(A) when is_atom(A) -> A. lk(Key, L) -> {value, {_,Val}} = lists:keysearch(Key, 1, L), Val. t2l(L) -> map(fun(T) -> tail(tuple_to_list(T)) end, L). tail([]) -> []; tail(L) -> tl(L). str2term(Str) -> hd(str2terms(Str ++ ". ")). %% str2tokens:str2terms("{hello,23}. [arne,43]. 5.6. {5.5,1.0}. "). %% ==> [{hello,23},[arne,43],5.60000,{5.50000,1.00000}] str2terms(String) -> tokenlists2terms(str2tokenlists(String)). str2tokenlists("") -> []; str2tokenlists(String) -> case erl_scan:tokens([], String, 1) of {done, {ok, Tokens, _}, Rest} -> [Tokens | str2tokenlists(Rest)] end. tokenlists2terms(Lists) -> lists:map(fun(L) -> {ok, Term} = erl_parse:parse_term(L), Term end, Lists). yaws-2.0.2/contrib/yaws_content_negotiation.erl0000664000175000017500000001422212605311412016676 00000000000000-module(yaws_content_negotiation). -export([compute_rsva/2, parse_accept_field/1, match_media_type/2]). -include("../include/yaws_api.hrl"). %% TODO: analyze impact of spaces in headers; when/where to strip? %% RFC 2296 compute_rsva(Arg, VariantList) -> Headers = Arg#arg.headers, Accept = parse_accept_field(Headers#headers.accept), % move these into #headers{} ! AcceptCharset = parse_accept_field( get_other_header('Accept-Charset', Headers)), AcceptLanguage = parse_accept_field( get_other_header('Accept-Language', Headers)), AcceptFeatures = [], % yet to be implemented RankedVariants = overall_quality(VariantList, Accept, AcceptCharset, AcceptLanguage, AcceptFeatures), case determine_result(RankedVariants) of none -> %% TODO: build Alternates: header field VariantList; URI -> %% TODO: must be neighbour variant (same root as request) URI end. get_other_header(Name, Headers) -> case lists:keysearch(Name, 3, Headers#headers.other) of {value, {_,_,Name,_,Field}} -> Field; false -> undefined end. determine_result(V) -> determine_result(V, {[], {0,1}}). determine_result([{URI,{Q,X}}|T], {_,{AccQ,_}}) when Q > AccQ -> determine_result(T, {URI,{Q,X}}); determine_result([_|T], Acc) -> determine_result(T, Acc); determine_result([], {URI,{_,0}}) -> URI; determine_result([], _) -> none. overall_quality(VariantList, Accept, AcceptCharset, AcceptLanguage, AcceptFeatures) -> overall_quality(VariantList, Accept, AcceptCharset, AcceptLanguage, AcceptFeatures, []). overall_quality([{URI,Qs,Attributes}|T], Accept, AcceptCharset, AcceptLanguage, AcceptFeatures, Acc) -> %% QX = {Qvalue, [0=definitive, >0=speculative]} Qt = case {lists:keysearch(type, 1, Attributes), Accept} of {false, _} -> {1000, 0}; {_, []} -> {1000, 1}; {{value, {type, MediaType}}, Accept} -> match_media_type(MediaType, Accept) end, Qc = case {lists:keysearch(charset, 1, Attributes), AcceptCharset} of {false, _} -> {1000, 0}; {_, []} -> {1000, 1}; {{value, {charset, Charset}}, AcceptCharset} -> match_charset(Charset, AcceptCharset) end, Ql = case {lists:keysearch(language, 1, Attributes), AcceptLanguage} of {false, _} -> {1000, 0}; {_, []} -> {1000, 1}; {{value, {language, Languages}}, AcceptLanguage} -> match_language(Languages, AcceptLanguage) end, Qf = {1000, 0}, % Accept-Features: not yet implemented Q = round5(Qs, Qt, Qc, Ql, Qf), overall_quality(T, Accept, AcceptCharset, AcceptLanguage, AcceptFeatures, [{URI, Q}|Acc]); %% fallback-variant overall_quality([URI|T], Accept, AcceptCharset, AcceptLanguage, AcceptFeatures, Acc) when is_list(URI) -> Q = {1, 0}, % {0.000001, definitive} overall_quality(T, Accept, AcceptCharset, AcceptLanguage, AcceptFeatures, [{URI, Q}|Acc]); overall_quality([], _Accept, _AcceptCharset, _AcceptLanguage, _AcceptFeatures, Acc) -> Acc. %% this functions rounds to five decimal places but to avoid %% using floats we have 1 represent 0.000001 and 1000000 = 1.0 round5(Qs, {Qt, A}, {Qc, B}, {Ql, C}, {Qf, D}) -> Q = ((Qs * 1000) * (Qt * 1000) * (Qc * 1000) * (Ql * 1000) * (Qf * 1000)), {((Q div 10000000000000000000000000) * 10), (A+B+C+D)}. match_media_type(MediaType, AcceptRanges) -> case lists:keysearch(MediaType, 1, AcceptRanges) of {ok, {_, Q}} -> {Q, 0}; false -> [SimpleMediaType|_] = yaws:split_sep(MediaType, $;), match_media_type_simple(SimpleMediaType, AcceptRanges) end. match_media_type_simple(SimpleMediaType, AcceptRanges) -> case lists:keysearch(SimpleMediaType, 1, AcceptRanges) of {ok, {_, Q}} -> {Q, 0}; false -> [Type|_] = yaws:split_sep(SimpleMediaType, $/), match_media_type_only(Type, AcceptRanges) end. match_media_type_only(Type, AcceptRanges) -> case lists:keysearch(Type++"/*", 1, AcceptRanges) of {ok, {_, Q}} -> {Q, 1}; false -> case lists:keysearch("*/*", 1, AcceptRanges) of {ok, {_, Q}} -> {Q, 1}; false -> {0, 0} end end. match_charset(Charset, AcceptCharset) -> case lists:keysearch(Charset, 1, AcceptCharset) of {ok, {_, Q}} -> {Q, 0}; false -> {0, 0} end. match_language(Languages, AcceptLanguage) -> match_language(Languages, AcceptLanguage, 0). match_language([Language|T], AcceptLanguage, Qacc) -> Qacc1 = case lists:keysearch(Language, 1, AcceptLanguage) of {ok, {_, Q1}} when Q1 > Qacc -> Q1; _ -> Qacc end, Qacc2 = case yaws:split_sep(Language, $-) of [H|T] when length(T) > 0 -> case lists:keysearch(H, 1, AcceptLanguage) of {ok, {_, Q2}} when Q2 > Qacc1 -> Q2; _ -> Qacc1 end; [Language] -> Qacc1 end, match_language(T, AcceptLanguage, Qacc2); match_language([], AcceptLanguage, Qacc) -> case lists:keysearch("*", 1, AcceptLanguage) of {ok, {_, Q}} when Q > Qacc -> {Q, 1}; _ -> {Qacc, 0} end. parse_accept_field(undefined) -> []; parse_accept_field(Field) -> parse_accept_field(yaws:split_sep(Field, $,), []). parse_accept_field([H|T], Acc) -> R = parse_accept_element(yaws:split_sep(H, $;)), parse_accept_field(T, Acc ++ [R]); parse_accept_field([], Acc) -> Acc. parse_accept_element(L) -> parse_accept_element(L, []). parse_accept_element(["q="++Q|_], Acc) -> {Acc, yaws:parse_qvalue(Q)}; parse_accept_element([H|T], []) -> parse_accept_element(T, H); parse_accept_element([H|T], Acc) -> parse_accept_element(T, Acc++";"++H); parse_accept_element([], Acc) -> {Acc, 1000}. yaws-2.0.2/priv/0000775000175000017500000000000012605312014010453 500000000000000yaws-2.0.2/priv/Makefile.in0000664000175000017500000004123412605311446012454 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = priv DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(dist_priv_DATA) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(privdir)" DATA = $(dist_priv_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ privdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/priv dist_priv_DATA = mime.types $(wildcard @srcdir@/*.xsd) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign priv/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign priv/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_privDATA: $(dist_priv_DATA) @$(NORMAL_INSTALL) @list='$(dist_priv_DATA)'; test -n "$(privdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(privdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(privdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(privdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(privdir)" || exit $$?; \ done uninstall-dist_privDATA: @$(NORMAL_UNINSTALL) @list='$(dist_priv_DATA)'; test -n "$(privdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(privdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(privdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_privDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_privDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-dist_privDATA install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-dist_privDATA # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/priv/xml.xsd0000664000175000017500000002120412605311412011713 00000000000000

About the XML namespace

This schema document describes the XML namespace, in a form suitable for import by other schema documents.

See http://www.w3.org/XML/1998/namespace.html and http://www.w3.org/TR/REC-xml for information about this namespace.

Note that local names in this namespace are intended to be defined only by the World Wide Web Consortium or its subgroups. The names currently defined in this namespace are listed below. They should not be used with conflicting semantics by any Working Group, specification, or document instance.

See further below in this document for more information about how to refer to this schema document from your own XSD schema documents and about the namespace-versioning policy governing this schema document.

lang (as an attribute name)

denotes an attribute whose value is a language code for the natural language of the content of any element; its value is inherited. This name is reserved by virtue of its definition in the XML specification.

Notes

Attempting to install the relevant ISO 2- and 3-letter codes as the enumerated possible values is probably never going to be a realistic possibility.

See BCP 47 at http://www.rfc-editor.org/rfc/bcp/bcp47.txt and the IANA language subtag registry at http://www.iana.org/assignments/language-subtag-registry for further information.

The union allows for the 'un-declaration' of xml:lang with the empty string.

space (as an attribute name)

denotes an attribute whose value is a keyword indicating what whitespace processing discipline is intended for the content of the element; its value is inherited. This name is reserved by virtue of its definition in the XML specification.

base (as an attribute name)

denotes an attribute whose value provides a URI to be used as the base for interpreting any relative URIs in the scope of the element on which it appears; its value is inherited. This name is reserved by virtue of its definition in the XML Base specification.

See http://www.w3.org/TR/xmlbase/ for information about this attribute.

id (as an attribute name)

denotes an attribute whose value should be interpreted as if declared to be of type ID. This name is reserved by virtue of its definition in the xml:id specification.

See http://www.w3.org/TR/xml-id/ for information about this attribute.

Father (in any context at all)

denotes Jon Bosak, the chair of the original XML Working Group. This name is reserved by the following decision of the W3C XML Plenary and XML Coordination groups:

In appreciation for his vision, leadership and dedication the W3C XML Plenary on this 10th day of February, 2000, reserves for Jon Bosak in perpetuity the XML name "xml:Father".

About this schema document

This schema defines attributes and an attribute group suitable for use by schemas wishing to allow xml:base, xml:lang, xml:space or xml:id attributes on elements they define.

To enable this, such a schema must import this schema for the XML namespace, e.g. as follows:

          <schema . . .>
           . . .
           <import namespace="http://www.w3.org/XML/1998/namespace"
                      schemaLocation="http://www.w3.org/2001/xml.xsd"/>
     

or

           <import namespace="http://www.w3.org/XML/1998/namespace"
                      schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
     

Subsequently, qualified reference to any of the attributes or the group defined below will have the desired effect, e.g.

          <type . . .>
           . . .
           <attributeGroup ref="xml:specialAttrs"/>
     

will define a type which will schema-validate an instance element with any of those attributes.

Versioning policy for this schema document

In keeping with the XML Schema WG's standard versioning policy, this schema document will persist at http://www.w3.org/2009/01/xml.xsd.

At the date of issue it can also be found at http://www.w3.org/2001/xml.xsd.

The schema document at that URI may however change in the future, in order to remain compatible with the latest version of XML Schema itself, or with the XML namespace itself. In other words, if the XML Schema or XML namespaces change, the version of this document at http://www.w3.org/2001/xml.xsd will change accordingly; the version at http://www.w3.org/2009/01/xml.xsd will not change.

Previous dated (and unchanging) versions of this schema document are at:

yaws-2.0.2/priv/wsdl.xsd0000664000175000017500000002657712605311412012106 00000000000000 This type is extended by component types to allow them to be documented This type is extended by component types to allow attributes from other namespaces to be added. This type is extended by component types to allow elements from other namespaces to be added. Any top level optional element allowed to appear more then once - any child of definitions element except wsdl:types. Any extensibility element is allowed in any place. yaws-2.0.2/priv/wsdl11soap12.xsd0000664000175000017500000001430212605311412013255 00000000000000 yaws-2.0.2/priv/soap-envelope.xsd0000664000175000017500000001276212605311412013701 00000000000000 Elements replacing the wildcard MUST be namespace qualified, but can be in the targetNamespace Fault reporting structure yaws-2.0.2/priv/mime.types0000664000175000017500000012501612605311412012416 00000000000000# This is the mime.types file from the Apache web server svn trunk: # # http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types # # Updated 13 Apr 2014. Local modifications were also applied. The original text # from the top of the Apache source file is below: # # This file maps Internet media types to unique file extension(s). # Although created for httpd, this file is used by many software systems # and has been placed in the public domain for unlimited redisribution. # # The table below contains both registered and (common) unregistered types. # A type that has no unique extension can be ignored -- they are listed # here to guide configurations toward known types and to make it easier to # identify "new" types. File extensions are also commonly used to indicate # content languages and encodings, so choose them carefully. # # Internet media types should be registered as described in RFC 4288. # The registry is at . # # MIME type (lowercased) Extensions # ============================================ ========== application/activemessage application/andrew-inset ez application/applefile application/applixware aw application/atom+xml atom application/atomcat+xml atomcat application/atomicmail application/atomsvc+xml atomsvc application/auth-policy+xml application/batch-smtp application/beep+xml application/cals-1840 application/ccxml+xml ccxml application/cdmi-capability cdmia application/cdmi-container cdmic application/cdmi-domain cdmid application/cdmi-object cdmio application/cdmi-queue cdmiq application/cea-2018+xml application/cellml+xml application/cnrp+xml application/commonground application/conference-info+xml application/cpl+xml application/csta+xml application/cstadata+xml application/cu-seeme cu application/cybercash application/davmount+xml davmount application/dca-rft application/dec-dx application/dialog-info+xml application/dicom application/dns application/docbook+xml dbk application/dssc+der dssc application/dssc+xml xdssc application/dvcs application/ecmascript ecma application/edi-consent application/edi-x12 application/edifact application/emma+xml emma application/epp+xml application/epub+zip epub application/eshop application/example application/exi exi application/fastinfoset application/fastsoap application/fits application/font-tdpfr pfr application/font-woff woff application/gml+xml gml application/gpx+xml gpx application/gxf gxf application/h224 application/http application/hyperstudio stk application/ibe-key-request+xml application/ibe-pkg-reply+xml application/ibe-pp-data application/iges application/im-iscomposing+xml application/index application/index.cmd application/index.obj application/index.response application/index.vnd application/inkml+xml ink inkml application/iotp application/ipfix ipfix application/ipp application/isup application/java-archive jar application/java-serialized-object ser application/java-vm class application/javascript js application/json json application/jsonml+json jsonml application/kpml-request+xml application/kpml-response+xml application/lost+xml lostxml application/mac-binhex40 hqx application/mac-compactpro cpt application/macwriteii application/mads+xml mads application/marc mrc application/marcxml+xml mrcx application/mathematica ma nb mb application/mathematica-old application/mathml+xml mathml application/mbms-associated-procedure-description+xml application/mbms-deregister+xml application/mbms-envelope+xml application/mbms-msk+xml application/mbms-msk-response+xml application/mbms-protection-description+xml application/mbms-reception-report+xml application/mbms-register+xml application/mbms-register-response+xml application/mbms-user-service-description+xml application/mbox mbox application/media_control+xml application/mediaservercontrol+xml mscml application/metalink+xml metalink application/metalink4+xml meta4 application/mets+xml mets application/mikey application/mods+xml mods application/moss-keys application/moss-signature application/mosskey-data application/mosskey-request application/mp21 m21 mp21 application/mp4 mp4s application/mpeg4-generic application/mpeg4-iod application/mpeg4-iod-xmt application/msword doc dot application/mxf mxf application/nasdata application/news-checkgroups application/news-groupinfo application/news-message-id application/news-transmission application/nss application/ocsp-request application/ocsp-response application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy application/oda oda application/oebps-package+xml opf application/ogg ogx application/omdoc+xml omdoc application/onenote onetoc onetoc2 onetmp onepkg application/oxps oxps application/parityfec application/patch-ops-error+xml xer application/pdf pdf application/pgp-encrypted pgp application/pgp-keys application/pgp-signature asc sig application/pics-rules prf application/pidf+xml application/pidf-diff+xml application/pkcs10 p10 application/pkcs7-mime p7m p7c application/pkcs7-signature p7s application/pkcs8 p8 application/pkix-attr-cert ac application/pkix-cert cer application/pkix-crl crl application/pkix-pkipath pkipath application/pkixcmp pki application/pls+xml pls application/poc-settings+xml application/postscript ai eps ps application/prs.alvestrand.titrax-sheet application/prs.cww cww application/prs.nprend application/prs.plucker application/pskc+xml pskcxml application/qsig application/rdf+xml rdf application/reginfo+xml rif application/relax-ng-compact-syntax rnc application/remote-printing application/resource-lists+xml rl application/resource-lists-diff+xml rld application/riscos application/rlmi+xml application/rls-services+xml rs application/rpki-ghostbusters gbr application/rpki-manifest mft application/rpki-roa roa application/rsd+xml rsd application/rss+xml rss application/rtf rtf application/rtx application/samlassertion+xml application/samlmetadata+xml application/sbml+xml sbml application/scvp-cv-request scq application/scvp-cv-response scs application/scvp-vp-request spq application/scvp-vp-response spp application/sdp sdp application/set-payment application/set-payment-initiation setpay application/set-registration application/set-registration-initiation setreg application/sgml application/sgml-open-catalog application/shf+xml shf application/sieve application/simple-filter+xml application/simple-message-summary application/simplesymbolcontainer application/slate application/smil smi smil application/smil+xml smi smil application/soap+fastinfoset application/soap+xml application/sparql-query rq application/sparql-results+xml srx application/spirits-event+xml application/srgs gram application/srgs+xml grxml application/sru+xml sru application/ssdl+xml ssdl application/ssml+xml ssml application/tei+xml tei teicorpus application/thraud+xml tfi application/timestamp-query application/timestamp-reply application/timestamped-data tsd application/tve-trigger application/ulpfec application/vemmi application/vividence.scriptfile application/vnd.3M.Post-it-Notes application/vnd.3gpp.bsf+xml application/vnd.3gpp.pic-bw-large plb application/vnd.3gpp.pic-bw-small psb application/vnd.3gpp.pic-bw-var pvb application/vnd.3gpp.sms application/vnd.3gpp2.bcmcsinfo+xml application/vnd.3gpp2.sms application/vnd.3gpp2.tcap tcap application/vnd.3m.post-it-notes pwn application/vnd.FloGraphIt application/vnd.accpac.simply.aso aso application/vnd.accpac.simply.imp imp application/vnd.acucobol acu application/vnd.acucorp atc acutc application/vnd.adobe.air-application-installer-package+zip air application/vnd.adobe.formscentral.fcdt fcdt application/vnd.adobe.fxp fxp fxpl application/vnd.adobe.xdp+xml xdp application/vnd.adobe.xfdf xfdf application/vnd.aether.imp application/vnd.ahead.space ahead application/vnd.airzip.filesecure.azf azf application/vnd.airzip.filesecure.azs azs application/vnd.amazon.ebook azw application/vnd.americandynamics.acc acc application/vnd.amiga.ami ami application/vnd.android.package-archive apk application/vnd.anser-web-certificate-issue-initiation cii application/vnd.anser-web-funds-transfer-initiation fti application/vnd.antix.game-component atx application/vnd.apple.installer+xml mpkg application/vnd.apple.mpegurl m3u8 application/vnd.arastra.swi swi application/vnd.aristanetworks.swi swi application/vnd.astraea-software.iota iota application/vnd.audiograph aep application/vnd.autopackage application/vnd.avistar+xml application/vnd.blueice.multipass mpm application/vnd.bluetooth.ep.oob application/vnd.bmi bmi application/vnd.businessobjects rep application/vnd.cab-jscript application/vnd.canon-cpdl application/vnd.canon-lips application/vnd.cendio.thinlinc.clientconf application/vnd.chemdraw+xml cdxml application/vnd.chipnuts.karaoke-mmd mmd application/vnd.cinderella cdy application/vnd.cirpack.isdn-ext application/vnd.claymore cla application/vnd.cloanto.rp9 rp9 application/vnd.clonk.c4group c4g c4d c4f c4p c4u application/vnd.cluetrust.cartomobile-config c11amc application/vnd.cluetrust.cartomobile-config-pkg c11amz application/vnd.commerce-battelle application/vnd.commonspace csp application/vnd.comsocaller application/vnd.contact.cmsg cdbcmsg application/vnd.cosmocaller cmc application/vnd.crick.clicker clkx application/vnd.crick.clicker.keyboard clkk application/vnd.crick.clicker.palette clkp application/vnd.crick.clicker.template clkt application/vnd.crick.clicker.wordbank clkw application/vnd.criticaltools.wbs+xml wbs application/vnd.ctc-posml pml application/vnd.ctct.ws+xml application/vnd.cups-pdf application/vnd.cups-postscript application/vnd.cups-ppd ppd application/vnd.cups-raster application/vnd.cups-raw application/vnd.curl.car car application/vnd.curl.pcurl pcurl application/vnd.cybank application/vnd.dart dart application/vnd.data-vision.rdz rdz application/vnd.dece.data uvf uvvf uvd uvvd application/vnd.dece.ttml+xml uvt uvvt application/vnd.dece.unspecified uvx uvvx application/vnd.dece.zip uvz uvvz application/vnd.denovo.fcselayout-link fe_launch application/vnd.dir-bi.plate-dl-nosuffix application/vnd.dna dna application/vnd.dolby.mlp mlp application/vnd.dolby.mobile.1 application/vnd.dolby.mobile.2 application/vnd.dpgraph dpg application/vnd.dreamfactory dfac application/vnd.ds-keypoint kpxx application/vnd.dvb.ait ait application/vnd.dvb.esgcontainer application/vnd.dvb.ipdcdftnotifaccess application/vnd.dvb.ipdcesgaccess application/vnd.dvb.ipdcroaming application/vnd.dvb.iptv.alfec-base application/vnd.dvb.iptv.alfec-enhancement application/vnd.dvb.notif-aggregate-root+xml application/vnd.dvb.notif-container+xml application/vnd.dvb.notif-generic+xml application/vnd.dvb.notif-ia-msglist+xml application/vnd.dvb.notif-ia-registration-request+xml application/vnd.dvb.notif-ia-registration-response+xml application/vnd.dvb.notif-init+xml application/vnd.dvb.service svc application/vnd.dxr application/vnd.dynageo geo application/vnd.ecdis-update application/vnd.ecowin.chart mag application/vnd.ecowin.filerequest application/vnd.ecowin.fileupdate application/vnd.ecowin.series application/vnd.ecowin.seriesrequest application/vnd.ecowin.seriesupdate application/vnd.emclient.accessrequest+xml application/vnd.enliven nml application/vnd.epson.esf esf application/vnd.epson.msf msf application/vnd.epson.quickanime qam application/vnd.epson.salt slt application/vnd.epson.ssf ssf application/vnd.ericsson.quickcall application/vnd.eszigno3+xml es3 et3 application/vnd.etsi.aoc+xml application/vnd.etsi.cug+xml application/vnd.etsi.iptvcommand+xml application/vnd.etsi.iptvdiscovery+xml application/vnd.etsi.iptvprofile+xml application/vnd.etsi.iptvsad-bc+xml application/vnd.etsi.iptvsad-cod+xml application/vnd.etsi.iptvsad-npvr+xml application/vnd.etsi.iptvueprofile+xml application/vnd.etsi.mcid+xml application/vnd.etsi.sci+xml application/vnd.etsi.simservs+xml application/vnd.eudora.data application/vnd.ezpix-album ez2 application/vnd.ezpix-package ez3 application/vnd.f-secure.mobile application/vnd.fdf fdf application/vnd.fdsn.mseed mseed application/vnd.fdsn.seed seed dataless application/vnd.ffsns application/vnd.fints application/vnd.flographit gph application/vnd.fluxtime.clip ftc application/vnd.font-fontforge-sfd application/vnd.framemaker fm frame maker book application/vnd.frogans.fnc fnc application/vnd.frogans.ltf ltf application/vnd.fsc.weblaunch fsc application/vnd.fujitsu.oasys oas application/vnd.fujitsu.oasys2 oa2 application/vnd.fujitsu.oasys3 oa3 application/vnd.fujitsu.oasysgp fg5 application/vnd.fujitsu.oasysprs bh2 application/vnd.fujixerox.art-ex application/vnd.fujixerox.art4 application/vnd.fujixerox.ddd ddd application/vnd.fujixerox.docuworks xdw application/vnd.fujixerox.docuworks.binder xbd application/vnd.fujixerox.hbpl application/vnd.fut-misnet application/vnd.fuzzysheet fzs application/vnd.genomatix.tuxedo txd application/vnd.geogebra.file ggb application/vnd.geogebra.tool ggt application/vnd.geometry-explorer gex gre application/vnd.geonext gxt application/vnd.geoplan g2w application/vnd.geospace g3w application/vnd.gmx gmx application/vnd.google-earth.kml+xml kml application/vnd.google-earth.kmz kmz application/vnd.grafeq gqf gqs application/vnd.gridmp application/vnd.groove-account gac application/vnd.groove-help ghf application/vnd.groove-identity-message gim application/vnd.groove-injector grv application/vnd.groove-tool-message gtm application/vnd.groove-tool-template tpl application/vnd.groove-vcard vcg application/vnd.hal+xml hal application/vnd.handheld-entertainment+xml zmm application/vnd.hbci hbci application/vnd.hcl-bireports application/vnd.hhe.lesson-player les application/vnd.hp-HPGL application/vnd.hp-PCL application/vnd.hp-PCLXL application/vnd.hp-hpgl hpgl application/vnd.hp-hpid hpid application/vnd.hp-hps hps application/vnd.hp-jlyt jlt application/vnd.hp-pcl pcl application/vnd.hp-pclxl pclxl application/vnd.httphone application/vnd.hydrostatix.sof-data sfd-hdstx application/vnd.hzn-3d-crossword x3d application/vnd.ibm.MiniPay application/vnd.ibm.afplinedata application/vnd.ibm.electronic-media application/vnd.ibm.minipay mpy application/vnd.ibm.modcap afp listafp list3820 application/vnd.ibm.rights-management irm application/vnd.ibm.secure-container sc application/vnd.iccprofile icc icm application/vnd.igloader igl application/vnd.immervision-ivp ivp application/vnd.immervision-ivu ivu application/vnd.informedcontrol.rms+xml application/vnd.informix-visionary application/vnd.insors.igm igm application/vnd.intercon.formnet xpw xpx application/vnd.intergeo i2g application/vnd.intertrust.digibox application/vnd.intertrust.nncp application/vnd.intu.qbo qbo application/vnd.intu.qfx qfx application/vnd.iptc.g2.conceptitem+xml application/vnd.iptc.g2.knowledgeitem+xml application/vnd.iptc.g2.newsitem+xml application/vnd.iptc.g2.packageitem+xml application/vnd.ipunplugged.rcprofile rcprofile application/vnd.irepository.package+xml irp application/vnd.is-xpr xpr application/vnd.isac.fcs fcs application/vnd.jam jam application/vnd.japannet-directory-service application/vnd.japannet-jpnstore-wakeup application/vnd.japannet-payment-wakeup application/vnd.japannet-registration application/vnd.japannet-registration-wakeup application/vnd.japannet-setstore-wakeup application/vnd.japannet-verification application/vnd.japannet-verification-wakeup application/vnd.jcp.javame.midlet-rms rms application/vnd.jisp jisp application/vnd.joost.joda-archive joda application/vnd.kahootz ktz ktr application/vnd.kde.karbon karbon application/vnd.kde.kchart chrt application/vnd.kde.kformula kfo application/vnd.kde.kivio flw application/vnd.kde.kontour kon application/vnd.kde.kpresenter kpr kpt application/vnd.kde.kspread ksp application/vnd.kde.kword kwd kwt application/vnd.kenameaapp htke application/vnd.kidspiration kia application/vnd.kinar kne knp application/vnd.koan skp skd skt skm application/vnd.kodak-descriptor sse application/vnd.las.las+xml lasxml application/vnd.liberty-request+xml application/vnd.llamagraphics.life-balance.desktop lbd application/vnd.llamagraphics.life-balance.exchange+xml lbe application/vnd.lotus-1-2-3 123 application/vnd.lotus-approach apr application/vnd.lotus-freelance pre application/vnd.lotus-notes nsf application/vnd.lotus-organizer org application/vnd.lotus-screencam scm application/vnd.lotus-wordpro lwp application/vnd.macports.portpkg portpkg application/vnd.marlin.drm.actiontoken+xml application/vnd.marlin.drm.conftoken+xml application/vnd.marlin.drm.license+xml application/vnd.marlin.drm.mdcf application/vnd.mcd mcd application/vnd.medcalcdata mc1 application/vnd.mediastation.cdkey cdkey application/vnd.meridian-slingshot application/vnd.mfer mwf application/vnd.mfmp mfm application/vnd.micrografx.flo flo application/vnd.micrografx.igx igx application/vnd.mif mif application/vnd.minisoft-hp3000-save application/vnd.mitsubishi.misty-guard.trustweb application/vnd.mobius.daf daf application/vnd.mobius.dis dis application/vnd.mobius.mbk mbk application/vnd.mobius.mqy mqy application/vnd.mobius.msl msl application/vnd.mobius.plc plc application/vnd.mobius.txf txf application/vnd.mophun.application mpn application/vnd.mophun.certificate mpc application/vnd.motorola.flexsuite application/vnd.motorola.flexsuite.adsi application/vnd.motorola.flexsuite.fis application/vnd.motorola.flexsuite.gotap application/vnd.motorola.flexsuite.kmr application/vnd.motorola.flexsuite.ttc application/vnd.motorola.flexsuite.wem application/vnd.motorola.iprm application/vnd.mozilla.xul+xml xul application/vnd.ms-artgalry cil application/vnd.ms-asf application/vnd.ms-cab-compressed cab application/vnd.ms-excel xls xlm xla xlc xlt xlw application/vnd.ms-excel.addin.macroenabled.12 xlam application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb application/vnd.ms-excel.sheet.macroenabled.12 xlsm application/vnd.ms-excel.template.macroenabled.12 xltm application/vnd.ms-fontobject eot application/vnd.ms-htmlhelp chm application/vnd.ms-ims ims application/vnd.ms-lrm lrm application/vnd.ms-office.activex+xml application/vnd.ms-officetheme thmx application/vnd.ms-pki.seccat cat application/vnd.ms-pki.stl stl application/vnd.ms-playready.initiator+xml application/vnd.ms-powerpoint ppt pps pot application/vnd.ms-powerpoint.addin.macroenabled.12 ppam application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm application/vnd.ms-powerpoint.slide.macroenabled.12 sldm application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm application/vnd.ms-powerpoint.template.macroenabled.12 potm application/vnd.ms-project mpp mpt application/vnd.ms-tnef application/vnd.ms-wmdrm.lic-chlg-req application/vnd.ms-wmdrm.lic-resp application/vnd.ms-wmdrm.meter-chlg-req application/vnd.ms-wmdrm.meter-resp application/vnd.ms-word.document.macroenabled.12 docm application/vnd.ms-word.template.macroenabled.12 dotm application/vnd.ms-works wps wks wcm wdb application/vnd.ms-wpl wpl application/vnd.ms-xpsdocument xps application/vnd.mseq mseq application/vnd.msign application/vnd.multiad.creator application/vnd.multiad.creator.cif application/vnd.music-niff application/vnd.musician mus application/vnd.muvee.style msty application/vnd.mynfc taglet application/vnd.ncd.control application/vnd.ncd.reference application/vnd.nervana application/vnd.netfpx application/vnd.neurolanguage.nlu nlu application/vnd.nitf ntf nitf application/vnd.noblenet-directory nnd application/vnd.noblenet-sealer nns application/vnd.noblenet-web nnw application/vnd.nokia.catalogs application/vnd.nokia.conml+wbxml application/vnd.nokia.conml+xml application/vnd.nokia.iptv.config+xml application/vnd.nokia.isds-radio-presets application/vnd.nokia.landmark+wbxml application/vnd.nokia.landmark+xml application/vnd.nokia.landmarkcollection+xml application/vnd.nokia.n-gage.ac+xml application/vnd.nokia.n-gage.data ngdat application/vnd.nokia.n-gage.symbian.install n-gage application/vnd.nokia.ncd application/vnd.nokia.pcd+wbxml application/vnd.nokia.pcd+xml application/vnd.nokia.radio-preset rpst application/vnd.nokia.radio-presets rpss application/vnd.novadigm.EDM application/vnd.novadigm.EDX application/vnd.novadigm.EXT application/vnd.novadigm.edm edm application/vnd.novadigm.edx edx application/vnd.novadigm.ext ext application/vnd.oasis.opendocument.chart odc application/vnd.oasis.opendocument.chart-template otc application/vnd.oasis.opendocument.database odb application/vnd.oasis.opendocument.formula odf application/vnd.oasis.opendocument.formula-template odft application/vnd.oasis.opendocument.graphics odg application/vnd.oasis.opendocument.graphics-template otg application/vnd.oasis.opendocument.image odi application/vnd.oasis.opendocument.image-template oti application/vnd.oasis.opendocument.presentation odp application/vnd.oasis.opendocument.presentation-template otp application/vnd.oasis.opendocument.spreadsheet ods application/vnd.oasis.opendocument.spreadsheet-template ots application/vnd.oasis.opendocument.text odt application/vnd.oasis.opendocument.text-master odm application/vnd.oasis.opendocument.text-template ott application/vnd.oasis.opendocument.text-web oth application/vnd.obn application/vnd.olpc-sugar xo application/vnd.oma-scws-config application/vnd.oma-scws-http-request application/vnd.oma-scws-http-response application/vnd.oma.bcast.associated-procedure-parameter+xml application/vnd.oma.bcast.drm-trigger+xml application/vnd.oma.bcast.imd+xml application/vnd.oma.bcast.ltkm application/vnd.oma.bcast.notification+xml application/vnd.oma.bcast.provisioningtrigger application/vnd.oma.bcast.sgboot application/vnd.oma.bcast.sgdd+xml application/vnd.oma.bcast.sgdu application/vnd.oma.bcast.simple-symbol-container application/vnd.oma.bcast.smartcard-trigger+xml application/vnd.oma.bcast.sprov+xml application/vnd.oma.bcast.stkm application/vnd.oma.dcd application/vnd.oma.dcdc application/vnd.oma.dd2+xml dd2 application/vnd.oma.drm.risd+xml application/vnd.oma.group-usage-list+xml application/vnd.oma.poc.detailed-progress-report+xml application/vnd.oma.poc.final-report+xml application/vnd.oma.poc.groups+xml application/vnd.oma.poc.invocation-descriptor+xml application/vnd.oma.poc.optimized-progress-report+xml application/vnd.oma.xcap-directory+xml application/vnd.omads-email+xml application/vnd.omads-file+xml application/vnd.omads-folder+xml application/vnd.omaloc-supl-init application/vnd.openofficeorg.extension oxt application/vnd.openxmlformats-officedocument.presentationml.presentation pptx application/vnd.openxmlformats-officedocument.presentationml.slide sldx application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx application/vnd.openxmlformats-officedocument.presentationml.template potx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx application/vnd.openxmlformats-officedocument.wordprocessingml.document docx application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx application/vnd.osa.netdeploy application/vnd.osgeo.mapguide.package mgp application/vnd.osgi.bundle application/vnd.osgi.dp dp application/vnd.osgi.subsystem esa application/vnd.otps.ct-kip+xml application/vnd.palm pdb pqa oprc application/vnd.paos.xml application/vnd.pawaafile paw application/vnd.pg.format str application/vnd.pg.osasli ei6 application/vnd.piaccess.application-licence application/vnd.picsel efif application/vnd.pmi.widget wg application/vnd.poc.group-advertisement+xml application/vnd.pocketlearn plf application/vnd.powerbuilder6 pbd application/vnd.powerbuilder6-s application/vnd.powerbuilder7 application/vnd.powerbuilder7-s application/vnd.powerbuilder75 application/vnd.powerbuilder75-s application/vnd.preminet application/vnd.previewsystems.box box application/vnd.proteus.magazine mgz application/vnd.publishare-delta-tree qps application/vnd.pvi.ptid1 ptid application/vnd.pwg-multiplexed application/vnd.pwg-xhtml-print+xml application/vnd.qualcomm.brew-app-res application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb application/vnd.rapid application/vnd.realvnc.bed bed application/vnd.recordare.musicxml mxl application/vnd.recordare.musicxml+xml musicxml application/vnd.renlearn.rlprint application/vnd.rig.cryptonote cryptonote application/vnd.rim.cod cod application/vnd.rn-realmedia rm application/vnd.rn-realmedia-vbr rmvb application/vnd.route66.link66+xml link66 application/vnd.ruckus.download application/vnd.s3sms application/vnd.sailingtracker.track st application/vnd.sbm.cid application/vnd.sbm.mid2 application/vnd.scribus application/vnd.sealed.3df application/vnd.sealed.csf application/vnd.sealed.doc application/vnd.sealed.eml application/vnd.sealed.mht application/vnd.sealed.net application/vnd.sealed.ppt application/vnd.sealed.tiff application/vnd.sealed.xls application/vnd.sealedmedia.softseal.html application/vnd.sealedmedia.softseal.pdf application/vnd.seemail see application/vnd.sema sema application/vnd.semd semd application/vnd.semf semf application/vnd.shana.informed.formdata ifm application/vnd.shana.informed.formtemplate itp application/vnd.shana.informed.interchange iif application/vnd.shana.informed.package ipk application/vnd.simtech-mindmapper twd twds application/vnd.smaf mmf application/vnd.smart.teacher teacher application/vnd.software602.filler.form+xml application/vnd.software602.filler.form-xml-zip application/vnd.solent.sdkm+xml sdkm sdkd application/vnd.spotfire.dxp dxp application/vnd.spotfire.sfs sfs application/vnd.sss-cod application/vnd.sss-dtf application/vnd.sss-ntf application/vnd.stardivision.calc sdc application/vnd.stardivision.draw sda application/vnd.stardivision.impress sdd application/vnd.stardivision.math smf application/vnd.stardivision.writer sdw vor application/vnd.stardivision.writer-global sgl application/vnd.stepmania.package smzip application/vnd.stepmania.stepchart sm application/vnd.street-stream application/vnd.sun.wadl+xml application/vnd.sun.xml.calc sxc application/vnd.sun.xml.calc.template stc application/vnd.sun.xml.draw sxd application/vnd.sun.xml.draw.template std application/vnd.sun.xml.impress sxi application/vnd.sun.xml.impress.template sti application/vnd.sun.xml.math sxm application/vnd.sun.xml.writer sxw application/vnd.sun.xml.writer.global sxg application/vnd.sun.xml.writer.template stw application/vnd.sus-calendar sus susp application/vnd.svd svd application/vnd.swiftview-ics application/vnd.symbian.install sis sisx application/vnd.syncml+xml xsm application/vnd.syncml.dm+wbxml bdm application/vnd.syncml.dm+xml xdm application/vnd.syncml.dm.notification application/vnd.syncml.ds.notification application/vnd.tao.intent-module-archive tao application/vnd.tcpdump.pcap pcap cap dmp application/vnd.tmobile-livetv tmo application/vnd.trid.tpt tpt application/vnd.triscape.mxs mxs application/vnd.trueapp tra application/vnd.truedoc application/vnd.tve-trigger application/vnd.ufdl ufd ufdl application/vnd.uiq.theme utz application/vnd.umajin umj application/vnd.unity unityweb application/vnd.uoml+xml uoml application/vnd.uplanet.alert application/vnd.uplanet.alert-wbxml application/vnd.uplanet.bearer-choice application/vnd.uplanet.bearer-choice-wbxml application/vnd.uplanet.cacheop application/vnd.uplanet.cacheop-wbxml application/vnd.uplanet.channel application/vnd.uplanet.channel-wbxml application/vnd.uplanet.list application/vnd.uplanet.list-wbxml application/vnd.uplanet.listcmd application/vnd.uplanet.listcmd-wbxml application/vnd.uplanet.signal application/vnd.vcx vcx application/vnd.vd-study application/vnd.vectorworks application/vnd.vidsoft.vidconference application/vnd.visio vsd vst vss vsw application/vnd.visionary vis application/vnd.vividence.scriptfile application/vnd.vsf vsf application/vnd.wap.sic sic application/vnd.wap.slc slc application/vnd.wap.wbxml wbxml application/vnd.wap.wmlc wmlc application/vnd.wap.wmlscriptc wmlsc application/vnd.webturbo wtb application/vnd.wfa.wsc application/vnd.wmc application/vnd.wmf.bootstrap application/vnd.wolfram.player nbp application/vnd.wordperfect wpd application/vnd.wqd wqd application/vnd.wrq-hp3000-labelled application/vnd.wt.stf stf application/vnd.wv.csp+wbxml application/vnd.wv.csp+xml application/vnd.wv.ssp+xml application/vnd.xara xar application/vnd.xfdl xfdl application/vnd.xfdl.webform application/vnd.xmi+xml application/vnd.xmpie.cpkg application/vnd.xmpie.dpkg application/vnd.xmpie.plan application/vnd.xmpie.ppkg application/vnd.xmpie.xlim application/vnd.yamaha.hv-dic hvd application/vnd.yamaha.hv-script hvs application/vnd.yamaha.hv-voice hvp application/vnd.yamaha.openscoreformat osf application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg application/vnd.yamaha.smaf-audio saf application/vnd.yamaha.smaf-phrase spf application/vnd.yellowriver-custom-menu cmp application/vnd.zul zir zirz application/vnd.zzazz.deck+xml zaz application/voicexml+xml vxml application/watcherinfo+xml application/whoispp-query application/whoispp-response application/widget wgt application/winhlp hlp application/wita application/wordperfect5.1 application/wsdl+xml wsdl application/wspolicy+xml wspolicy application/x-7z-compressed 7z application/x-abiword abw application/x-ace-compressed ace application/x-apple-diskimage dmg application/x-authorware-bin aab x32 u32 vox application/x-authorware-map aam application/x-authorware-seg aas application/x-bcpio bcpio application/x-bittorrent torrent application/x-blorb blb blorb application/x-bzip bz application/x-bzip2 bz2 boz application/x-cbr cbr cba cbt cbz cb7 application/x-cdlink vcd application/x-cfs-compressed cfs application/x-chat chat application/x-chess-pgn pgn application/x-compress application/x-conference nsc application/x-cpio cpio application/x-csh csh application/x-debian-package deb udeb application/x-dgc-compressed dgc application/x-director dir dcr dxr cst cct cxt w3d fgd swa application/x-doom wad application/x-dtbncx+xml ncx application/x-dtbook+xml dtb application/x-dtbresource+xml res application/x-dvi dvi application/x-envoy evy application/x-eva eva application/x-font-bdf bdf application/x-font-dos application/x-font-framemaker application/x-font-ghostscript gsf application/x-font-libgrx application/x-font-linux-psf psf application/x-font-otf otf application/x-font-pcf pcf application/x-font-snf snf application/x-font-speedo application/x-font-sunos-news application/x-font-ttf ttf ttc application/x-font-type1 pfa pfb pfm afm application/x-font-vfont application/x-freearc arc application/x-futuresplash spl application/x-gca-compressed gca application/x-glulx ulx application/x-gnumeric gnumeric application/x-gramps-xml gramps application/x-gtar gtar application/x-gzip gz tgz application/x-hdf hdf application/x-install-instructions install application/x-iso9660-image iso application/x-java-jnlp-file jnlp application/x-javascript js application/x-kchart chrt application/x-killustrator kil application/x-koan skp skd skt skm application/x-kpresenter kpr kpt application/x-kspread ksp application/x-kword kwd kwt application/x-latex latex application/x-lzh-compressed lzh lha application/x-mie mie application/x-mobipocket-ebook prc mobi application/x-ms-application application application/x-ms-shortcut lnk application/x-ms-wmd wmd application/x-ms-wmz wmz application/x-ms-xbap xbap application/x-msaccess mdb application/x-msbinder obd application/x-mscardfile crd application/x-msclip clp application/x-msdownload exe dll com bat msi application/x-msmediaview mvb m13 m14 application/x-msmetafile wmf wmz emf emz application/x-msmoney mny application/x-mspublisher pub application/x-msschedule scd application/x-msterminal trm application/x-mswrite wri application/x-netcdf nc cdf application/x-ns-proxy-autoconfig pac application/x-nzb nzb application/x-pkcs12 p12 pfx application/x-pkcs7-certificates p7b spc application/x-pkcs7-certreqresp p7r application/x-rar-compressed rar application/x-research-info-systems ris application/x-rpm rpm application/x-sh sh application/x-shar shar application/x-shockwave-flash swf application/x-silverlight-app xap application/x-sql sql application/x-stuffit sit application/x-stuffitx sitx application/x-subrip srt application/x-sv4cpio sv4cpio application/x-sv4crc sv4crc application/x-t3vm-image t3 application/x-tads gam application/x-tar tar application/x-tcl tcl application/x-tex tex application/x-tex-tfm tfm application/x-texinfo texinfo texi application/x-tgif obj application/x-troff application/x-troff-man application/x-troff-me application/x-troff-ms ms application/x-ustar ustar application/x-wais-source src application/x-x509-ca-cert der crt application/x-xfig fig application/x-xliff+xml xlf application/x-xpinstall xpi application/x-xz xz application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8 application/x400-bp application/xaml+xml xaml application/xcap-att+xml application/xcap-caps+xml application/xcap-diff+xml xdf application/xcap-el+xml application/xcap-error+xml application/xcap-ns+xml application/xcon-conference-info+xml application/xcon-conference-info-diff+xml application/xenc+xml xenc application/xhtml+xml xhtml xht application/xhtml-voice+xml application/xml xml xsl application/xml-dtd dtd application/xml-external-parsed-entity application/xmpp+xml application/xop+xml xop application/xproc+xml xpl application/xslt+xml xslt application/xspf+xml xspf application/xv+xml mxml xhvml xvml xvm application/yang yang application/yin+xml yin application/zip zip audio/32kadpcm audio/3gpp audio/3gpp2 audio/ac3 audio/adpcm adp audio/amr audio/amr-wb audio/amr-wb+ audio/asc audio/basic au snd audio/bv16 audio/bv32 audio/clearmode audio/cn audio/dat12 audio/dls audio/dsr-es201108 audio/dsr-es202050 audio/dsr-es202211 audio/dsr-es202212 audio/dvi4 audio/eac3 audio/evrc audio/evrc-qcp audio/evrc0 audio/evrc1 audio/evrcb audio/evrcb0 audio/evrcb1 audio/evrcwb audio/evrcwb0 audio/evrcwb1 audio/example audio/g.722.1 audio/g719 audio/g722 audio/g7221 audio/g723 audio/g726-16 audio/g726-24 audio/g726-32 audio/g726-40 audio/g728 audio/g729 audio/g7291 audio/g729d audio/g729e audio/gsm audio/gsm-efr audio/ilbc audio/l16 audio/l20 audio/l24 audio/l8 audio/lpc audio/midi mid midi kar rmi audio/mobile-xmf audio/mp4 mp4a audio/mp4a-latm audio/mpa audio/mpa-robust audio/mpeg mpga mp2 mp2a mp3 m2a m3a audio/mpeg4-generic audio/ogg oga ogg spx audio/parityfec audio/pcma audio/pcma-wb audio/pcmu audio/pcmu-wb audio/prs.sid audio/qcelp audio/red audio/rtp-enc-aescm128 audio/rtp-midi audio/rtx audio/s3m s3m audio/silk sil audio/smv audio/smv-qcp audio/smv0 audio/sp-midi audio/t140c audio/t38 audio/telephone-event audio/tone audio/ulpfec audio/vdvi audio/vmr-wb audio/vnd.3gpp.iufp audio/vnd.4sb audio/vnd.audiokoz audio/vnd.celp audio/vnd.cisco.nse audio/vnd.cmles.radio-events audio/vnd.cns.anp1 audio/vnd.cns.inf1 audio/vnd.dece.audio uva uvva audio/vnd.digital-winds eol audio/vnd.dlna.adts audio/vnd.dolby.heaac.1 audio/vnd.dolby.heaac.2 audio/vnd.dolby.mlp audio/vnd.dolby.mps audio/vnd.dolby.pl2 audio/vnd.dolby.pl2x audio/vnd.dolby.pl2z audio/vnd.dra dra audio/vnd.dts dts audio/vnd.dts.hd dtshd audio/vnd.everad.plj audio/vnd.hns.audio audio/vnd.lucent.voice lvp audio/vnd.ms-playready.media.pya pya audio/vnd.nokia.mobile-xmf audio/vnd.nortel.vbk audio/vnd.nuera.ecelp4800 ecelp4800 audio/vnd.nuera.ecelp7470 ecelp7470 audio/vnd.nuera.ecelp9600 ecelp9600 audio/vnd.octel.sbc audio/vnd.qcelp audio/vnd.rhetorex.32kadpcm audio/vnd.rip rip audio/vnd.sealedmedia.softseal.mpeg audio/vnd.vmx.cvsd audio/vorbis audio/vorbis-config audio/webm weba audio/x-aac aac audio/x-aiff aif aiff aifc audio/x-caf caf audio/x-flac flac audio/x-matroska mka audio/x-mpegurl m3u audio/x-ms-wax wax audio/x-ms-wma wma audio/x-pn-realaudio ram ra audio/x-pn-realaudio-plugin rmp audio/x-realaudio ra audio/x-wav wav audio/xm xm chemical/x-cdx cdx chemical/x-cif cif chemical/x-cmdf cmdf chemical/x-cml cml chemical/x-csml csml chemical/x-pdb chemical/x-xyz xyz image/bmp bmp image/cgm cgm image/example image/fits image/g3fax g3 image/gif gif image/ief ief image/jp2 image/jpeg jpeg jpg jpe image/jpm image/jpx image/ktx ktx image/naplps image/png png image/prs.btif btif image/prs.pti image/sgi sgi image/svg+xml svg svgz image/t38 image/tiff tiff tif image/tiff-fx image/vnd.adobe.photoshop psd image/vnd.cns.inf2 image/vnd.dece.graphic uvi uvvi uvg uvvg image/vnd.djvu djvu djv image/vnd.dvb.subtitle sub image/vnd.dwg dwg image/vnd.dxf dxf image/vnd.fastbidsheet fbs image/vnd.fpx fpx image/vnd.fst fst image/vnd.fujixerox.edmics-mmr mmr image/vnd.fujixerox.edmics-rlc rlc image/vnd.globalgraphics.pgb image/vnd.microsoft.icon image/vnd.mix image/vnd.ms-modi mdi image/vnd.ms-photo wdp image/vnd.net-fpx npx image/vnd.radiance image/vnd.sealed.png image/vnd.sealedmedia.softseal.gif image/vnd.sealedmedia.softseal.jpg image/vnd.svf image/vnd.wap.wbmp wbmp image/vnd.xiff xif image/webp webp image/x-3ds 3ds image/x-cmu-raster ras image/x-cmx cmx image/x-freehand fh fhc fh4 fh5 fh7 image/x-icon ico image/x-mrsid-image sid image/x-pcx pcx image/x-pict pic pct image/x-portable-anymap pnm image/x-portable-bitmap pbm image/x-portable-graymap pgm image/x-portable-pixmap ppm image/x-rgb rgb image/x-tga tga image/x-xbitmap xbm image/x-xpixmap xpm image/x-xwindowdump xwd message/cpim message/delivery-status message/disposition-notification message/example message/external-body message/global message/global-delivery-status message/global-disposition-notification message/global-headers message/http message/imdn+xml message/news message/partial message/rfc822 eml mime message/s-http message/sip message/sipfrag message/tracking-status message/vnd.si.simp model/example model/iges igs iges model/mesh msh mesh silo model/vnd.collada+xml dae model/vnd.dwf dwf model/vnd.flatland.3dml model/vnd.gdl gdl model/vnd.gs-gdl model/vnd.gs.gdl model/vnd.gtw gtw model/vnd.moml+xml model/vnd.mts mts model/vnd.parasolid.transmit.binary model/vnd.parasolid.transmit.text model/vnd.vtu vtu model/vrml wrl vrml model/x3d+binary x3db x3dbz model/x3d+vrml x3dv x3dvz model/x3d+xml x3d x3dz multipart/alternative multipart/appledouble multipart/byteranges multipart/digest multipart/encrypted multipart/example multipart/form-data multipart/header-set multipart/mixed multipart/parallel multipart/related multipart/report multipart/signed multipart/voice-message text/cache-manifest appcache text/calendar ics ifb text/css css text/csv csv text/directory text/dns text/ecmascript text/enriched text/example text/html html htm text/javascript text/n3 n3 text/parityfec text/plain txt text conf def list log in text/prs.fallenstein.rst text/prs.lines.tag dsc text/red text/rfc822-headers text/richtext rtx text/rtf rtf text/rtp-enc-aescm128 text/rtx text/sgml sgml sgm text/t140 text/tab-separated-values tsv text/troff t tr roff man me ms text/turtle ttl text/ulpfec text/uri-list uri uris urls text/vcard vcard text/vnd.DMClientScript text/vnd.IPTC.NITF text/vnd.IPTC.NewsML text/vnd.abc text/vnd.curl curl text/vnd.curl.dcurl dcurl text/vnd.curl.mcurl mcurl text/vnd.curl.scurl scurl text/vnd.dmclientscript text/vnd.dvb.subtitle sub text/vnd.esmertec.theme-descriptor text/vnd.flatland.3dml text/vnd.fly fly text/vnd.fmi.flexstor flx text/vnd.graphviz gv text/vnd.in3d.3dml 3dml text/vnd.in3d.spot spot text/vnd.iptc.newsml text/vnd.iptc.nitf text/vnd.latex-z text/vnd.motorola.reflex text/vnd.ms-mediapackage text/vnd.net2phone.commcenter.command text/vnd.si.uricatalogue text/vnd.sun.j2me.app-descriptor jad text/vnd.trolltech.linguist text/vnd.wap.si si text/vnd.wap.sl sl text/vnd.wap.wml wml text/vnd.wap.wmlscript wmls text/x-asm s asm text/x-c c cc cxx cpp h hh dic text/x-fortran f for f77 f90 text/x-java-source java text/x-nfo nfo text/x-opml opml text/x-pascal p pas text/x-setext etx text/x-sfv sfv text/x-uuencode uu text/x-vcalendar vcs text/x-vcard vcf text/xml xml xsl text/xml-external-parsed-entity video/3gpp 3gp video/3gpp-tt video/3gpp2 3g2 video/bmpeg video/bt656 video/celb video/dv video/example video/h261 h261 video/h263 h263 video/h263-1998 video/h263-2000 video/h264 h264 video/jpeg jpgv video/jpeg2000 video/jpm jpm jpgm video/mj2 mj2 mjp2 video/mp1s video/mp2p video/mp2t ts video/mp4 mp4 mp4v mpg4 video/mp4v-es video/mpeg mpeg mpg mpe m1v m2v video/mpeg4-generic video/mpv video/nv video/ogg ogv video/parityfec video/pointer video/quicktime qt mov video/raw video/rtp-enc-aescm128 video/rtx video/smpte292m video/ulpfec video/vc1 video/vnd.cctv video/vnd.dece.hd uvh uvvh video/vnd.dece.mobile uvm uvvm video/vnd.dece.mp4 video/vnd.dece.pd uvp uvvp video/vnd.dece.sd uvs uvvs video/vnd.dece.video uvv uvvv video/vnd.dlna.mpeg-tts video/vnd.dvb.file dvb video/vnd.fvt fvt video/vnd.hns.video video/vnd.iptvforum.1dparityfec-1010 video/vnd.iptvforum.1dparityfec-2005 video/vnd.iptvforum.2dparityfec-1010 video/vnd.iptvforum.2dparityfec-2005 video/vnd.iptvforum.ttsavc video/vnd.iptvforum.ttsmpeg2 video/vnd.motorola.video video/vnd.motorola.videop video/vnd.mpegurl mxu m4u video/vnd.ms-playready.media.pyv pyv video/vnd.mts video/vnd.nokia.interleaved-multimedia video/vnd.nokia.videovoip video/vnd.objectvideo video/vnd.sealed.mpeg1 video/vnd.sealed.mpeg4 video/vnd.sealed.swf video/vnd.sealedmedia.softseal.mov video/vnd.uvvu.mp4 uvu uvvu video/vnd.vivo viv video/webm webm video/x-f4v f4v video/x-fli fli video/x-flv flv video/x-m4v m4v video/x-matroska mkv mk3d mks video/x-mng mng video/x-ms-asf asf asx video/x-ms-vob vob video/x-ms-wm wm video/x-ms-wmv wmv video/x-ms-wmx wmx video/x-ms-wvx wvx video/x-msvideo avi video/x-sgi-movie movie video/x-smv smv x-conference/x-cooltalk ice yaws-2.0.2/priv/envelope.xsd0000664000175000017500000001371212605311412012735 00000000000000 Prose in the spec does not specify that attributes are allowed on the Body element 'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element. For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification Fault reporting structure yaws-2.0.2/priv/soap.xsd0000664000175000017500000001330212605311412012055 00000000000000 "encodingStyle" indicates any canonicalization conventions followed in the contents of the containing element. For example, the value "http://schemas.xmlsoap.org/soap/encoding/" indicates the pattern described in SOAP specification yaws-2.0.2/priv/Makefile.am0000664000175000017500000000022312605311412012425 00000000000000privdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/priv dist_priv_DATA = mime.types $(wildcard @srcdir@/*.xsd) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/rebar.config0000664000175000017500000000161012605311412011674 00000000000000%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ft=erlang ts=4 sw=4 et {require_min_otp_vsn, "R14B02"}. {sub_dirs, ["rel"]}. {erl_opts, [{platform_define, "(linux|solaris|freebsd|darwin)", 'HAVE_SENDFILE'}, {src_dirs, ["src", "examples/src"]}, warnings_as_errors]}. {port_env, [{"CFLAGS", "$CFLAGS -g -O3 -Wall -I/usr/include/security"}, {"x86_64", "CFLAGS", "$CFLAGS -m$ERLANG_ARCH"}, {"x86_64", "LDFLAGS", "-m$ERLANG_ARCH $LDFLAGS"}, {"i[36]86", "CFLAGS", "$CFLAGS -m$ERLANG_ARCH"}, {"i[36]86", "LDFLAGS", "-m$ERLANG_ARCH $LDFLAGS"} ]}. {port_specs, [{"priv/lib/epam.so", ["c_src/epam.c"]}, {"priv/lib/setuid_drv.so", ["c_src/setuid_drv.c"]}]}. {pre_hooks, [{compile, "./scripts/rebar-pre-script"}, {clean, "./scripts/rebar-pre-script clean"}]}. yaws-2.0.2/erlang_deps.mk0000664000175000017500000000042012605311412012224 00000000000000incdep = include $(DEPDIR)/$(1) $(eval $(shell $(MKDIR_P) $(DEPDIR))) $(foreach module,$(MODULES), $(shell touch $(DEPDIR)/$(module:%.erl=%.Pbeam))) $(foreach module,$(MODULES), $(eval $(call incdep,$(module:%.erl=%.Pbeam)))) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/0000775000175000017500000000000012605312015010453 500000000000000yaws-2.0.2/test/t14/0000775000175000017500000000000012605312015011063 500000000000000yaws-2.0.2/test/t14/Makefile.in0000664000175000017500000003616512605311446013072 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t14 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl EXTRA_DIST = $(MODULES) EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t14/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t14/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t14/app_test.erl0000664000175000017500000000272412605311413013334 00000000000000-module(app_test). -compile(export_all). -include_lib("ibrowse/include/ibrowse.hrl"). -include("tftest.hrl"). %% Way to invoke just one test start([F]) -> ?line {ok, _} = ibrowse:start_link(), apply(app_test, F, []), ibrowse:stop(). start() -> io:format("\n ==== MAIN TESTS ==== \n\n", []), ?line {ok, _} = ibrowse:start_link(), test_missing_host_header(), test_multiple_host_header(), ibrowse:stop(). test_missing_host_header() -> io:format("missing Host header returns 400\n",[]), {ok,S} = gen_tcp:connect("localhost", 8000, [binary, {active,false}]), ok = gen_tcp:send(S, "GET / HTTP/1.1\r\n\r\n"), ok = do_recv(S, <<"HTTP/1.1 400 Bad Request\r\n">>), gen_tcp:close(S), ok. test_multiple_host_header() -> io:format("multiple Host headers returns 400\n",[]), {ok,S} = gen_tcp:connect("localhost", 8000, [binary, {active,false}]), ok = gen_tcp:send(S, ["GET / HTTP/1.1\r\n", "Host: localhost\r\n", "Host: foo\r\n\r\n"]), ok = do_recv(S, <<"HTTP/1.1 400 Bad Request\r\n">>), gen_tcp:close(S), ok. do_recv(Sock, Expected) -> Size = byte_size(Expected), inet:setopts(Sock, [{active,once}]), receive {tcp_closed,_} -> do_recv(Sock, Expected); {tcp,_,Result} -> ?line <> = Result; Wrong -> error({{expected,Expected},{received,Wrong}}) end, ok. yaws-2.0.2/test/t14/yaws.conf.in0000664000175000017500000000111012605311413013234 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true # For the Host header tests, the following must be false: pick_first_virthost_on_nomatch = false use_fdsrv = false keepalive_timeout = 10000 max_connections = 1 port = 8000 listen = 0.0.0.0 docroot = @abs_top_srcdir@/www yaws-2.0.2/test/t14/Makefile.am0000664000175000017500000000100712605311413013036 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl EXTRA_DIST = $(MODULES) EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/t5/0000775000175000017500000000000012605312015011003 500000000000000yaws-2.0.2/test/t5/Makefile.in0000664000175000017500000003740412605311446013007 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t5 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl \ emptytest.erl \ streamtest.erl \ smalltest.erl \ bigtest.erl EXTRA_DIST = $(MODULES) EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t5/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t5/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test prepare-test:: $(AM_V_at)touch ./docroot-test/0.txt $(AM_V_at)dd if=/dev/zero of=./docroot-test/1000.txt bs=1024 count=1000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/3000.txt bs=1024 count=3000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/10000.txt bs=1024 count=10000 >/dev/null 2>&1 $(AM_V_at)gzip -c ./docroot-test/10000.txt > ./docroot-test/10000.txt.gz $(AM_V_at)cp ./docroot-test/10000.txt.gz ./docroot-test/10000.txt.old.gz $(AM_V_at)sleep 1 $(AM_V_at)gunzip -c ./docroot-test/10000.txt.old.gz > ./docroot-test/10000.txt.old distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t5/emptytest.erl0000664000175000017500000000022512605311413013465 00000000000000-module(emptytest). -export([out/1]). -include("../../include/yaws.hrl"). -include("../../include/yaws_api.hrl"). out(_Arg) -> {status, 200}. yaws-2.0.2/test/t5/streamtest.erl0000664000175000017500000000065112605311413013625 00000000000000-module(streamtest). -export([out/1]). -include("../../include/yaws.hrl"). -include("../../include/yaws_api.hrl"). out(_Arg) -> yaws_api:stream_chunk_deliver(self(), "and this is the second one\n"), yaws_api:stream_chunk_deliver(self(), "con"), yaws_api:stream_chunk_deliver(self(), "sequence"), yaws_api:stream_chunk_end(self()), {streamcontent, "text/plain", "This is the data in the first chunk\n"}. yaws-2.0.2/test/t5/smalltest.erl0000664000175000017500000000025412605311413013441 00000000000000-module(smalltest). -export([out/1]). -include("../../include/yaws.hrl"). -include("../../include/yaws_api.hrl"). out(_Arg) -> [{status, 200}, {page, "/1000.txt"}]. yaws-2.0.2/test/t5/bigtest.erl0000664000175000017500000000025212605311413013070 00000000000000-module(bigtest). -export([out/1]). -include("../../include/yaws.hrl"). -include("../../include/yaws_api.hrl"). out(_Arg) -> [{status, 200}, {page, "/3000.txt"}]. yaws-2.0.2/test/t5/app_test.erl0000664000175000017500000003365512605311413013263 00000000000000-module(app_test). -compile(export_all). -include_lib("ibrowse/include/ibrowse.hrl"). -include("tftest.hrl"). %% Way to invoke just one test start([F]) -> ?line {ok, _} = ibrowse:start_link(), apply(app_test, F, []), ibrowse:stop(). start() -> io:format("\n ==== DEFLATE TESTS ==== \n\n", []), ?line {ok, _} = ibrowse:start_link(), deflate_disabled(), deflate_enabled(), deflate_empty_response(), deflate_streamcontent(), deflate_options(), ibrowse:stop(). deflate_disabled() -> io:format("deflate_disabled\n", []), %% Static content (and cached) - Not supported by server Uri1 = "http://localhost:8000/1000.txt", ?line {ok, "200", Hdrs1, _} = ibrowse:send_req(Uri1, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs1), ?line undefined = proplists:get_value("Vary", Hdrs1), %% Dynamic content - Not supported by server Uri2 = "http://localhost:8000/index.yaws", ?line {ok, "200", Hdrs2, _} = ibrowse:send_req(Uri2, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs2), ?line undefined = proplists:get_value("Vary", Hdrs2), %% Static content (and cached) - Not supported by client Uri3 = "http://localhost:8001/1000.txt", ?line {ok, "200", Hdrs3, _} = ibrowse:send_req(Uri3, [], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs3), ?line "Accept-Encoding" = proplists:get_value("Vary", Hdrs3), %% Dynamic content - Not supported by client Uri4 = "http://localhost:8001/index.yaws", ?line {ok, "200", Hdrs4, _} = ibrowse:send_req(Uri4, [], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs4), ?line "Accept-Encoding" = proplists:get_value("Vary", Hdrs4), ok. deflate_enabled() -> io:format("deflate_enabled\n", []), %% Static content (and catched) Uri1 = "http://localhost:8001/1000.txt", ?line {ok, "200", Hdrs1, Body1} = ibrowse:send_req(Uri1, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs1), ?line "Accept-Encoding" = proplists:get_value("Vary", Hdrs1), ?line true = is_binary(zlib:gunzip(Body1)), %% Partial content is not compressed for small (and cached) files Uri2 = "http://localhost:8001/1000.txt", ?line {ok, "206", Hdrs2, _} = ibrowse:send_req(Uri2, [{"Accept-Encoding", "gzip, deflate"}, {"Range", "bytes=100-499"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs2), ?line "400" = proplists:get_value("Content-Length", Hdrs2), ?line "Accept-Encoding" = proplists:get_value("Vary", Hdrs2), %% Dynamic content Uri3 = "http://localhost:8001/index.yaws", ?line {ok, "200", Hdrs3, Body3} = ibrowse:send_req(Uri3, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs3), ?line "Accept-Encoding" = proplists:get_value("Vary", Hdrs3), ?line true = is_binary(zlib:gunzip(Body3)), ok. deflate_empty_response() -> io:format("deflate_empty_response\n", []), %% Static content Uri1 = "http://localhost:8000/0.txt", ?line {ok, "200", Hdrs1, _} = ibrowse:send_req(Uri1, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs1), ?line "0" = proplists:get_value("Content-Length", Hdrs1), ?line undefined = proplists:get_value("Vary", Hdrs1), Uri2 = "http://localhost:8001/0.txt", ?line {ok, "200", Hdrs2, _} = ibrowse:send_req(Uri2, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs2), ?line "0" = proplists:get_value("Content-Length", Hdrs2), ?line undefined = proplists:get_value("Vary", Hdrs2), %% Dynamic content Uri3 = "http://localhost:8000/emptytest", ?line {ok, "200", Hdrs3, _} = ibrowse:send_req(Uri3, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs3), ?line "0" = proplists:get_value("Content-Length", Hdrs3), ?line undefined = proplists:get_value("Vary", Hdrs3), Uri4 = "http://localhost:8001/emptytest", ?line {ok, "200", Hdrs4, _} = ibrowse:send_req(Uri4, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs4), ?line "0" = proplists:get_value("Content-Length", Hdrs4), ?line undefined = proplists:get_value("Vary", Hdrs4), ok. deflate_streamcontent() -> io:format("deflate_streamcontent\n", []), %% Static content (cannot be cached so the file is chunked) Uri1 = "http://localhost:8001/10000.txt", ?line {ok, "200", Hdrs1, _} = ibrowse:send_req(Uri1, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs1), ?line "chunked" = proplists:get_value("Transfer-Encoding", Hdrs1), ?line undefined = proplists:get_value("Content-Length", Hdrs1), ?line "Accept-Encoding" = proplists:get_value("Vary", Hdrs1), %% Partial content is not compressed for large files Uri2 = "http://localhost:8001/10000.txt", ?line {ok, "206", Hdrs2, _} = ibrowse:send_req(Uri2, [{"Accept-Encoding", "gzip, deflate"}, {"Range", "bytes=500-599"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs2), ?line undefined = proplists:get_value("Transfer-Encoding", Hdrs2), ?line "100" = proplists:get_value("Content-Length", Hdrs2), ?line "Accept-Encoding" = proplists:get_value("Vary", Hdrs2), %% Dynamic content (chunked) Uri3 = "http://localhost:8001/streamtest", ?line {ok, "200", Hdrs3, _} = ibrowse:send_req(Uri3, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs3), ?line "chunked" = proplists:get_value("Transfer-Encoding", Hdrs3), ?line undefined = proplists:get_value("Content-Length", Hdrs3), ?line "Accept-Encoding" = proplists:get_value("Vary", Hdrs3), ok. deflate_options() -> io:format("deflate_options\n", []), deflate_mime_types(), deflate_compress_size(), deflate_gzip_static(), deflate_otheroptions(), ok. deflate_mime_types() -> io:format(" deflate_mime_types\n", []), %% image/gif not compressed on localhost:8001 Uri1 = "http://localhost:8001/icons/yaws.gif", ?line {ok, "200", Hdrs1, _} = ibrowse:send_req(Uri1, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs1), %% application/* compressed on localhost:8002 but text/plain not Uri2 = "http://localhost:8002/1000.txt", ?line {ok, "200", Hdrs2, _} = ibrowse:send_req(Uri2, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs2), Uri3 = "http://localhost:8002/yaws.eps", ?line {ok, "200", Hdrs3, Body3} = ibrowse:send_req(Uri3, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs3), ?line true = is_binary(zlib:gunzip(Body3)), %% application/* and text/* compressed on localhost:8003 Uri4 = "http://localhost:8003/1000.txt", ?line {ok, "200", Hdrs4, Body4} = ibrowse:send_req(Uri4, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs4), ?line true = is_binary(zlib:gunzip(Body4)), Uri5 = "http://localhost:8003/yaws.eps", ?line {ok, "200", Hdrs5, Body5} = ibrowse:send_req(Uri5, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs5), ?line true = is_binary(zlib:gunzip(Body5)), %% All mime types are compressed on localhost:8004 Uri6 = "http://localhost:8004/1000.txt", ?line {ok, "200", Hdrs6, Body6} = ibrowse:send_req(Uri6, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs6), ?line true = is_binary(zlib:gunzip(Body6)), Uri7 = "http://localhost:8004/yaws.eps", ?line {ok, "200", Hdrs7, Body7} = ibrowse:send_req(Uri7, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs7), ?line true = is_binary(zlib:gunzip(Body7)), ok. deflate_compress_size() -> io:format(" deflate_compress_size\n", []), %% Small static content (cached) Uri1 = "http://localhost:8005/1000.txt", ?line {ok, "200", Hdrs1, _} = ibrowse:send_req(Uri1, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs1), Uri2 = "http://localhost:8005/3000.txt", ?line {ok, "200", Hdrs2, Body2} = ibrowse:send_req(Uri2, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs2), ?line true = is_binary(zlib:gunzip(Body2)), %% Large static content (cached) Uri3 = "http://localhost:8005/10000.txt", ?line {ok, "200", Hdrs3, Body3} = ibrowse:send_req(Uri3, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs3), ?line true = is_binary(zlib:gunzip(Body3)), Uri4 = "http://localhost:8008/10000.txt", ?line {ok, "200", Hdrs4, _} = ibrowse:send_req(Uri4, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs4), %% Dynamic content Uri5 = "http://localhost:8005/smalltest", ?line {ok, "200", Hdrs5, _} = ibrowse:send_req(Uri5, [{"Accept-Encoding", "gzip, deflate"}], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs5), Uri6 = "http://localhost:8005/bigtest", ?line {ok, "200", Hdrs6, Body6} = ibrowse:send_req(Uri6, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs6), ?line true = is_binary(zlib:gunzip(Body6)), ok. deflate_gzip_static() -> io:format(" deflate_gzip_static\n", []), %% when gzip_static is disabled, large static files are chunked Uri1 = "http://localhost:8006/10000.txt", ?line {ok, "200", Hdrs1, Body1} = ibrowse:send_req(Uri1, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs1), ?line "chunked" = proplists:get_value("Transfer-Encoding", Hdrs1), ?line undefined = proplists:get_value("Content-Length", Hdrs1), ?line true = is_binary(zlib:gunzip(Body1)), %% when gzip_static is enabled, if precompressed static file is found, the %% response is not chunked Uri2 = "http://localhost:8007/10000.txt", ?line {ok, "200", Hdrs2, Body2} = ibrowse:send_req(Uri2, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs2), ?line undefined = proplists:get_value("Transfer-Encoding", Hdrs2), ?line true = is_binary(zlib:gunzip(Body2)), ?line true = (zlib:gunzip(Body1) == zlib:gunzip(Body2)), %% if mtimes of compressed and uncompress files do not match, the compressed %% file is ignored Uri3 = "http://localhost:8007/10000.txt.old", ?line {ok, "200", Hdrs3, Body3} = ibrowse:send_req(Uri3, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs3), ?line "chunked" = proplists:get_value("Transfer-Encoding", Hdrs3), ?line undefined = proplists:get_value("Content-Length", Hdrs3), ?line true = is_binary(zlib:gunzip(Body3)), ok. deflate_otheroptions() -> io:format(" deflate_otheroptions\n", []), %% Static content Uri1 = "http://localhost:8006/1000.txt", ?line {ok, "200", Hdrs1, Body1} = ibrowse:send_req(Uri1, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs1), ?line true = is_binary(zlib:gunzip(Body1)), Uri2 = "http://localhost:8006/10000.txt", ?line {ok, "200", Hdrs2, Body2} = ibrowse:send_req(Uri2, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs2), ?line "chunked" = proplists:get_value("Transfer-Encoding", Hdrs2), ?line undefined = proplists:get_value("Content-Length", Hdrs2), ?line true = is_binary(zlib:gunzip(Body2)), %% Dynamic content Uri3 = "http://localhost:8006/smalltest", ?line {ok, "200", Hdrs3, Body3} = ibrowse:send_req(Uri3, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs3), ?line true = is_binary(zlib:gunzip(Body3)), Uri4 = "http://localhost:8006/bigtest", ?line {ok, "200", Hdrs4, Body4} = ibrowse:send_req(Uri4, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs4), ?line true = is_binary(zlib:gunzip(Body4)), Uri5 = "http://localhost:8006/streamtest", ?line {ok, "200", Hdrs5, Body5} = ibrowse:send_req(Uri5, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs5), ?line "chunked" = proplists:get_value("Transfer-Encoding", Hdrs5), ?line undefined = proplists:get_value("Content-Length", Hdrs5), ?line true = is_binary(zlib:gunzip(Body5)), ok, %% Multiple Accept-Encoding headers %% This test reuses Uri1 and Body1. It sends two Accept-Encoding %% headers to make sure Yaws handles them correctly. The reply %% should be the same as for the static content test at the beginning %% of this test function. ?line {ok, "200", Hdrs6, Body1} = ibrowse:send_req(Uri1, [{"Accept-Encoding", "identity;q=0.5"}, {"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs6), ok. yaws-2.0.2/test/t5/yaws.conf.in0000664000175000017500000000535512605311413013173 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 max_num_cached_bytes = 10485760 max_size_cached_file = 5120000 port = 8000 listen = 0.0.0.0 deflate = false appmods = emptytest streamtest docroot = @abs_builddir@/docroot-test @abs_top_srcdir@/www port = 8001 listen = 0.0.0.0 deflate = true appmods = emptytest streamtest docroot = @abs_builddir@/docroot-test @abs_top_srcdir@/www port = 8002 listen = 0.0.0.0 deflate = true docroot = @abs_builddir@/docroot-test @abs_top_srcdir@/www mime_types = application/* port = 8003 listen = 0.0.0.0 deflate = true docroot = @abs_builddir@/docroot-test @abs_top_srcdir@/www mime_types = defaults mime_types = application/* port = 8004 listen = 0.0.0.0 deflate = true docroot = @abs_builddir@/docroot-test @abs_top_srcdir@/www mime_types = all port = 8005 listen = 0.0.0.0 deflate = true docroot = @abs_builddir@/docroot-test @abs_top_srcdir@/www appmods = smalltest bigtest min_compress_size = 2048000 port = 8006 listen = 0.0.0.0 deflate = true docroot = @abs_builddir@/docroot-test @abs_top_srcdir@/www appmods = smalltest bigtest streamtest compression_level = best_speed mem_level = 9 strategy = huffman_only window_size = 9 port = 8007 listen = 0.0.0.0 deflate = true docroot = @abs_builddir@/docroot-test @abs_top_srcdir@/www use_gzip_static = true port = 8008 listen = 0.0.0.0 deflate = true docroot = @abs_builddir@/docroot-test @abs_top_srcdir@/www min_compress_size = 20480000 yaws-2.0.2/test/t5/Makefile.am0000664000175000017500000000223012605311413012755 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl \ emptytest.erl \ streamtest.erl \ smalltest.erl \ bigtest.erl EXTRA_DIST = $(MODULES) EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test prepare-test:: $(AM_V_at)touch ./docroot-test/0.txt $(AM_V_at)dd if=/dev/zero of=./docroot-test/1000.txt bs=1024 count=1000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/3000.txt bs=1024 count=3000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/10000.txt bs=1024 count=10000 >/dev/null 2>&1 $(AM_V_at)gzip -c ./docroot-test/10000.txt > ./docroot-test/10000.txt.gz $(AM_V_at)cp ./docroot-test/10000.txt.gz ./docroot-test/10000.txt.old.gz $(AM_V_at)sleep 1 $(AM_V_at)gunzip -c ./docroot-test/10000.txt.old.gz > ./docroot-test/10000.txt.old distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/Makefile.in0000664000175000017500000005265512605311446012464 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = src eunit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 \ t14 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ EXTRA_DIST = README include/tftest.hrl support/include.mk @MINGW_FALSE@SUBDIRS = src eunit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 @MINGW_FALSE@ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse @MINGW_FALSE@ERL_FLAGS = $(ERL_GENERIC_FLAGS) all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done @MINGW_FALSE@check-local: check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive @MINGW_TRUE@all-local: all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @MINGW_TRUE@clean-local: clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am check-local clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am @MINGW_FALSE@include @srcdir@/support/include.mk @MINGW_FALSE@all-local: @MINGW_FALSE@clean-local: @MINGW_FALSE@ $(AM_V_at)rm -rf ibrowse bin logs @MINGW_FALSE@test: check @MINGW_TRUE@check-local: @MINGW_TRUE@ @echo @MINGW_TRUE@ @echo " SKIPPED - Tests cannot be executed when Yaws is cross-compiled" @MINGW_TRUE@ @echo @MINGW_TRUE@test: check # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/include/0000775000175000017500000000000012605312014012075 500000000000000yaws-2.0.2/test/include/tftest.hrl0000664000175000017500000000035512605311413014042 00000000000000-define(line, put('$line',{?MODULE,?LINE}),). -define(srcdir, filename:dirname( proplists:get_value(source, ?MODULE:module_info(compile)) )). -define(builddir, filename:dirname(code:which(?MODULE))). yaws-2.0.2/test/t4/0000775000175000017500000000000012605312015011002 500000000000000yaws-2.0.2/test/t4/Makefile.in0000664000175000017500000004002212605311446012774 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t4 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl \ rewritetest.erl \ posttest.erl \ streamtest.erl \ nolengthtest.erl \ intercept1.erl \ intercept2.erl \ intercept3.erl EXTRA_DIST = $(MODULES) EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t4/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t4/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test prepare-test:: $(AM_V_at)mkdir docroot-test1 $(AM_V_at)mkdir docroot-test2 $(AM_V_at)echo "Hello World!" > docroot-test/index.html $(AM_V_at)echo "Hello World 1!" > docroot-test1/hello.txt $(AM_V_at)echo "Hello World 2!" > docroot-test2/hello.txt $(AM_V_at)dd if=/dev/zero of=./docroot-test/1000.txt bs=1024 count=1000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/2000.txt bs=1024 count=2000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/3000.txt bs=1024 count=3000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/10000.txt bs=1024 count=10000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test2/8388608.txt bs=1024 count=8192 >/dev/null 2>&1 clean-test:: $(AM_V_at)rm -fr docroot-test1 docroot-test2 distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t4/nolengthtest.erl0000664000175000017500000000066312605311413014152 00000000000000-module(nolengthtest). -export([out/1]). -include("../../include/yaws.hrl"). -include("../../include/yaws_api.hrl"). out(_Arg) -> yaws_api:stream_chunk_deliver(self(), lists:duplicate(256, $A)), yaws_api:stream_chunk_end(self()), [ {header, {transfer_encoding, erase}}, {header, {content_length, erase}}, {header, {connection, "close"}}, {streamcontent, "text/plain", lists:duplicate(256, $A)} ]. yaws-2.0.2/test/t4/streamtest.erl0000664000175000017500000000065112605311413013624 00000000000000-module(streamtest). -export([out/1]). -include("../../include/yaws.hrl"). -include("../../include/yaws_api.hrl"). out(_Arg) -> yaws_api:stream_chunk_deliver(self(), "and this is the second one\n"), yaws_api:stream_chunk_deliver(self(), "con"), yaws_api:stream_chunk_deliver(self(), "sequence"), yaws_api:stream_chunk_end(self()), {streamcontent, "text/plain", "This is the data in the first chunk\n"}. yaws-2.0.2/test/t4/posttest.erl0000664000175000017500000000652512605311413013324 00000000000000-module(posttest). -export([out/1]). -include("../../include/yaws.hrl"). -include("../../include/yaws_api.hrl"). out(Arg) -> Url = yaws_api:request_url(Arg), case Url#url.path of "/posttest/chunked/" ++ ExpectedSize -> TE = yaws:to_lower((Arg#arg.headers)#headers.transfer_encoding), if TE =:= "chunked" -> handle_post(list_to_integer(ExpectedSize), Arg); true -> Reason = io_lib:format("Expected a chunked transfer-encoding request\n~p", [Arg#arg.headers]), handle_post(0, Arg#arg{state={flush,500,Reason}}) end; "/posttest/" ++ ExpectedSize -> handle_post(list_to_integer(ExpectedSize), Arg); _ -> Reason = "unknown path: " ++ Url#url.path, handle_post(0, Arg#arg{state={flush,500,Reason}}) end. handle_post(_, #arg{clidata=Data, state={flush, HttpCode, Reason}}) -> %% Catch an error here but flush all remaining data. case Data of {partial, _} -> {get_more, undefined, {flush, HttpCode, Reason}}; _ -> [{status, HttpCode}, {html, Reason}] end; handle_post(ExpectedSize, #arg{clidata=Data, cont=undefined}=Arg) when is_binary(Data) -> %% This is not a partial request %% Expected: content_length =:= ExpectedSize AND %% content_length < partial_post_size. SC = get(sc), if size(Data) =:= ExpectedSize andalso size(Data) < SC#sconf.partial_post_size -> {status, 200}; true -> Reason = io_lib:format("Post data too big. " "Received: ~p bytes - Max: ~p bytes", [size(Data), SC#sconf.partial_post_size]), handle_post(ExpectedSize, Arg#arg{state={flush,500,Reason}}) end; handle_post(ExpectedSize, #arg{clidata={partial, Data}, cont=Cont}=Arg) when is_binary(Data) -> %% next Chunk of a partial request. if Cont =:= undefined -> %% First chunk {get_more, {cont, size(Data)}, undefined}; true -> {cont, Sz0} = Cont, Sz1 = Sz0 + size(Data), if Sz1 =< ExpectedSize -> {get_more, {cont, Sz1}, undefined}; true -> SC = get(sc), Reason = io_lib:format("Chunk too big. " "Received: ~p bytes - Max: ~p bytes", [size(Data), SC#sconf.partial_post_size]), handle_post(ExpectedSize, Arg#arg{state={flush,500,Reason}}) end end; handle_post(ExpectedSize, #arg{clidata=Data, cont=Cont}=Arg) when is_binary(Data) -> %% Last chunk of a partial request. {cont, Sz0} = Cont, Sz1 = Sz0 + size(Data), if Sz1 =:= ExpectedSize -> {status, 200}; true -> Reason = io_lib:format("Received data does not match " "the expected size. " "Received: ~p bytes - Expected: ~p bytes", [Sz1, ExpectedSize]), handle_post(ExpectedSize, Arg#arg{state={flush,500,Reason}}) end. yaws-2.0.2/test/t4/intercept1.erl0000664000175000017500000000042712605311413013510 00000000000000-module(intercept1). -export([rewrite_request/2, rewrite_response/2]). %% Test that returning an incorrect return value from rewrite_request %% is handled correctly by the reverse proxy. rewrite_request(_, _) -> error. rewrite_response(Resp, Hdrs) -> {ok, Resp, Hdrs}. yaws-2.0.2/test/t4/app_test.erl0000664000175000017500000002407012605311413013251 00000000000000-module(app_test). -compile(export_all). -include_lib("ibrowse/include/ibrowse.hrl"). -include("tftest.hrl"). %% Way to invoke just one test start([F]) -> ?line {ok, _} = ibrowse:start_link(), try apply(app_test, F, []), ok catch Error:Reason -> throw({Error, Reason}) after ibrowse:stop() end. start() -> io:format("\n ==== REVERSE PROXY TESTS ==== \n\n", []), ?line {ok, _} = ibrowse:start_link(), try deflate_revproxy_test1(), deflate_revproxy_test2(), test_post_revproxy(), test_streamcontent_revproxy(), test_keepalive_revproxy(), test_rewrite_revproxy(), test_large_content_revproxy(), test_no_content_length_revproxy(), test_failed_req_interception_revproxy(), test_failed_resp_interception_revproxy(), test_good_interception_revproxy(), test_fwdproxy(), test_ipv6_address(), ok catch Error:Reason -> throw({Error, Reason}) after ibrowse:stop() end. deflate_revproxy_test1() -> io:format("deflate_revproxy_test1\n", []), Uri = "http://localhost:8000/revproxy1/hello.txt", Res = "Hello World 1!\n", %% client: nodeflate - proxy: deflate - backend: deflate %% ==> result: uncompressed ?line {ok, "200", Hdrs1, Body1} = ibrowse:send_req(Uri, [], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs1), ?line Res = Body1, %% client: deflate - proxy: deflate - backend: deflate %% ==> result: compressed ?line {ok, "200", Hdrs2, Body2} = ibrowse:send_req(Uri, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs2), ?line Res = binary_to_list(zlib:gunzip(Body2)), ok. deflate_revproxy_test2() -> io:format("deflate_revproxy_test2\n", []), Uri = "http://localhost:8000/revproxy2/hello.txt", Res = "Hello World 2!\n", %% client: nodeflate - proxy: deflate - backend: nodeflate %% ==> result: uncompressed ?line {ok, "200", Hdrs1, Body1} = ibrowse:send_req(Uri, [], get), ?line undefined = proplists:get_value("Content-Encoding", Hdrs1), ?line Res = Body1, %% client: deflate - proxy: deflate - backend: nodeflate %% ==> result: compressed ?line {ok, "200", Hdrs2, Body2} = ibrowse:send_req(Uri, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs2), ?line Res = binary_to_list(zlib:gunzip(Body2)), ok. test_post_revproxy() -> io:format("post_revproxy_test\n",[]), small_post(), large_post(), small_chunked_post(), large_chunked_post(), ok. small_post() -> io:format(" small post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/1000.txt"), Sz = erlang:integer_to_list(size(Bin)), Uri = "http://localhost:8000/revproxy1/posttest/" ++ Sz, Hdrs = [{content_length, Sz}, {content_type, "binary/octet-stream"}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Hdrs, post, Bin, []), ok. large_post() -> io:format(" large post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/10000.txt"), Sz = erlang:integer_to_list(size(Bin)), Uri = "http://localhost:8000/revproxy1/posttest/" ++ Sz, Hdrs = [{content_length, Sz}, {content_type, "binary/octet-stream"}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Hdrs, post, Bin, []), ok. small_chunked_post() -> %% Chunk size is less than partial_post_size io:format(" small chunked post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/3000.txt"), Sz = erlang:integer_to_list(size(Bin)), Uri = "http://localhost:8000/revproxy1/posttest/chunked/" ++ Sz, Hdrs = [{content_type, "binary/octet-stream"}], Opts = [{transfer_encoding, {chunked, 1000*1000}}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Hdrs, post, Bin, Opts), ok. large_chunked_post() -> %% Chunk size is greater than partial_post_size io:format(" large chunked post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/10000.txt"), Sz = erlang:integer_to_list(size(Bin)), Uri = "http://localhost:8000/revproxy1/posttest/chunked/" ++ Sz, Hdrs = [{content_type, "binary/octet-stream"}], Opts = [{transfer_encoding, {chunked, 4000*1000}}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Hdrs, post, Bin, Opts), ok. test_streamcontent_revproxy() -> io:format("streamcontent_revproxy_test\n", []), Uri = "http://localhost:8000/revproxy1/streamtest", Res = "This is the data in the first chunk\n" "and this is the second one\n" "consequence", ?line {ok, "200", Hdrs1, Body1} = ibrowse:send_req(Uri, [], get), ?line "chunked" = proplists:get_value("Transfer-Encoding", Hdrs1), ?line Res = Body1, ?line {ok, "200", Hdrs2, Body2} = ibrowse:send_req(Uri, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "chunked" = proplists:get_value("Transfer-Encoding", Hdrs2), ?line Res = binary_to_list(zlib:gunzip(Body2)), ok. test_keepalive_revproxy() -> io:format("keepalive_revproxy_test\n", []), Path1 = "/revproxy1/hello.txt", Path2 = "/", Path3 = "/revproxy2/hello.txt", Res1 = "Hello World 1!\n", Res2 = "Hello World 2!\n", ?line {ok, Sock} = gen_tcp:connect("localhost", 8000, [list, {active, false}]), ?line ok = gen_tcp:send(Sock, "GET " ++ Path1 ++ " HTTP/1.1\r\n" "Host: localhost:8000\r\n" "Connection: Keep-Alive\r\n" "\r\n"), ?line {ok, Len1} = recv_hdrs(Sock), ?line {ok, Res1} = recv_body(Sock, Len1), ?line ok = gen_tcp:send(Sock, "GET " ++ Path2 ++ " HTTP/1.1\r\n" "Host: localhost:8000\r\n" "Connection: Keep-Alive\r\n" "\r\n"), ?line {ok, Len2} = recv_hdrs(Sock), ?line {ok, _} = recv_body(Sock, Len2), ?line ok = gen_tcp:send(Sock, "GET " ++ Path3 ++ " HTTP/1.1\r\n" "Host: localhost:8000\r\n" "Connection: Keep-Alive\r\n" "\r\n"), ?line {ok, Len3} = recv_hdrs(Sock), ?line {ok, Res2} = recv_body(Sock, Len3), gen_tcp:close(Sock), ok. test_rewrite_revproxy() -> io:format("rewrite_revproxy_test\n", []), Uri1 = "http://localhost:8000/rewrite/revproxy1/hello.txt", Uri2 = "http://localhost:8000/rewrite/revproxy2/hello.txt", Res1 = "Hello World 1!\n", Res2 = "Hello World 2!\n", ?line {ok, "200", _, Body1} = ibrowse:send_req(Uri1, [], get), ?line Res1 = Body1, ?line {ok, "200", _, Body2} = ibrowse:send_req(Uri2, [], get), ?line Res2 = Body2, ok. test_large_content_revproxy() -> io:format("large_content_revproxy_test\n", []), Uri = "http://localhost:8004/revproxy/8388608.txt", ?line {ok, Bin} = file:read_file(?builddir ++ "/docroot-test2/8388608.txt"), ?line {ok, "200", Hdrs, Body0} = ibrowse:send_req(Uri, [], get), ?line "8388608" = proplists:get_value("Content-Length", Hdrs), Body = list_to_binary(Body0), ?line true = (size(Body) == 8388608), ?line Bin = Body, ok. test_no_content_length_revproxy() -> io:format("no_content_length_revproxy_test\n", []), Uri = "http://localhost:8001/revproxy1/nolengthtest", Res = lists:duplicate(512, $A), ?line {ok, "200", Hdrs, Body} = ibrowse:send_req(Uri, [], get), ?line undefined = proplists:get_value("Content-Length", Hdrs), ?line undefined = proplists:get_value("Transfer-Encoding", Hdrs), ?line "close" = proplists:get_value("Connection", Hdrs), ?line Res = Body, ok. test_failed_req_interception_revproxy() -> io:format("failed_req_interception_revproxy_test\n", []), Uri = "http://localhost:8005/revproxy1/failedreqinterception", ?line {ok, "500", _, _} = ibrowse:send_req(Uri, [], get), ok. test_failed_resp_interception_revproxy() -> io:format("failed_resp_interception_revproxy_test\n", []), Uri = "http://localhost:8005/revproxy2/failedrespinterception", ?line {ok, "500", _, _} = ibrowse:send_req(Uri, [], get), ok. test_good_interception_revproxy() -> io:format("good_interception_revproxy_test\n", []), Uri = "http://localhost:8005/revproxy3/hello.txt", Res = "Hello World 2!\n", ?line {ok, "200", Hdrs, Body} = ibrowse:send_req(Uri, [], get), ?line Body = Res, ?line "true" = proplists:get_value("X-Test-Interception", Hdrs), ok. test_fwdproxy() -> io:format("fwdproxy_test\n", []), Uri1 = "http://localhost:8001/rewrite/hello.txt", Uri2 = "http://localhost:8002/rewrite/hello.txt", Res1 = "Hello World 1!\n", Res2 = "Hello World 2!\n", Opts = [{proxy_host, "localhost"}, {proxy_port, 8003}], ?line {ok, "200", _, Body1} = ibrowse:send_req(Uri1, [], get, [], Opts), ?line Res1 = Body1, ?line {ok, "200", _, Body2} = ibrowse:send_req(Uri2, [], get, [], Opts), ?line Res2 = Body2, ok. test_ipv6_address() -> io:format("revproxy_url_ipv6\n", []), Uri = "http://localhost:8000/revproxy3/hello.txt", Res = "Hello World 1!\n", ?line {ok, "200", _, Body} = ibrowse:send_req(Uri, [], get), ?line Body = Res, ok. recv_hdrs(Sock) -> inet:setopts(Sock, [{packet, http}]), recv_hdrs(Sock, 0). recv_hdrs(Sock, Len) -> inet:setopts(Sock, [{active, once}]), receive {http, Sock, http_eoh} -> {ok, Len}; {http, Sock, {http_error, Error}} -> {error, Error}; {http, Sock, {http_header, _, 'Content-Length', _, LenStr}} -> recv_hdrs(Sock, erlang:list_to_integer(LenStr)); {http, Sock, {http_header, _, _, _, _}} -> recv_hdrs(Sock, Len); {http, Sock, {http_response, _, 200, "OK"}} -> recv_hdrs(Sock, Len); Other -> {error, {"unexpected message", Other}} end. recv_body(Sock, Len) -> inet:setopts(Sock, [{packet, raw}, {active, false}]), gen_tcp:recv(Sock, Len). yaws-2.0.2/test/t4/rewritetest.erl0000664000175000017500000000062012605311413014006 00000000000000-module(rewritetest). -export([arg_rewrite/1]). -include("../../include/yaws.hrl"). -include("../../include/yaws_api.hrl"). arg_rewrite(Arg) -> Url = yaws_api:request_url(Arg), case Url#url.path of "/rewrite" ++ Rest -> Req0 = Arg#arg.req, Req1 = Req0#http_request{path={abs_path,Rest}}, Arg#arg{req=Req1}; _ -> Arg end. yaws-2.0.2/test/t4/yaws.conf.in0000664000175000017500000000366612605311413013175 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 port = 8000 listen = 0.0.0.0 deflate = true docroot = @abs_builddir@/docroot-test arg_rewrite_mod = rewritetest revproxy = /revproxy1 http://localhost:8001 revproxy = /revproxy2 http://localhost:8002 revproxy = /revproxy3 http://[::1]:8006 port = 8001 listen = 0.0.0.0 deflate = true partial_post_size = 2048000 docroot = @abs_builddir@/docroot-test1 appmods = posttest streamtest nolengthtest port = 8002 listen = 0.0.0.0 deflate = false docroot = @abs_builddir@/docroot-test2 port = 8003 listen = 0.0.0.0 deflate = false fwdproxy = true arg_rewrite_mod = rewritetest docroot = @abs_builddir@/docroot-test port = 8004 listen = 0.0.0.0 docroot = @abs_builddir@/docroot-test revproxy = /revproxy http://localhost:8002 port = 8005 listen = 0.0.0.0 docroot = @abs_builddir@/docroot-test revproxy = /revproxy1 http://localhost:8002 intercept_mod intercept1 revproxy = /revproxy2 http://localhost:8002 intercept_mod intercept2 revproxy = /revproxy3 http://localhost:8002 intercept_mod intercept3 port = 8006 listen = :: deflate = false docroot = @abs_builddir@/docroot-test1 yaws-2.0.2/test/t4/intercept3.erl0000664000175000017500000000047212605311413013512 00000000000000-module(intercept3). -export([rewrite_request/2, rewrite_response/2]). -include("../../include/yaws_api.hrl"). rewrite_request(Req, Hdrs) -> {ok, Req, yaws_api:set_header(Hdrs, accept, "text/plain")}. rewrite_response(Resp, Hdrs) -> {ok, Resp, yaws_api:set_header(Hdrs, "X-Test-Interception", "true")}. yaws-2.0.2/test/t4/intercept2.erl0000664000175000017500000000042512605311413013507 00000000000000-module(intercept2). -export([rewrite_request/2, rewrite_response/2]). rewrite_request(Req, Hdrs) -> {ok, Req, Hdrs}. %% Test that returning an incorrect return value from rewrite_request %% is handled correctly by the reverse proxy. rewrite_response(_, _) -> error. yaws-2.0.2/test/t4/Makefile.am0000664000175000017500000000264712605311413012770 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl \ rewritetest.erl \ posttest.erl \ streamtest.erl \ nolengthtest.erl \ intercept1.erl \ intercept2.erl \ intercept3.erl EXTRA_DIST = $(MODULES) EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test prepare-test:: $(AM_V_at)mkdir docroot-test1 $(AM_V_at)mkdir docroot-test2 $(AM_V_at)echo "Hello World!" > docroot-test/index.html $(AM_V_at)echo "Hello World 1!" > docroot-test1/hello.txt $(AM_V_at)echo "Hello World 2!" > docroot-test2/hello.txt $(AM_V_at)dd if=/dev/zero of=./docroot-test/1000.txt bs=1024 count=1000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/2000.txt bs=1024 count=2000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/3000.txt bs=1024 count=3000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/10000.txt bs=1024 count=10000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test2/8388608.txt bs=1024 count=8192 >/dev/null 2>&1 clean-test:: $(AM_V_at)rm -fr docroot-test1 docroot-test2 distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/t8/0000775000175000017500000000000012605312015011006 500000000000000yaws-2.0.2/test/t8/Makefile.in0000664000175000017500000003647612605311446013022 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t8 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ EXTRA_DIST = davtest davtest.in YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t8/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t8/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test check-local: $(EBIN_FILES) log start wait-started run-davtest stop wait-stopped log: @echo @echo " ==== WEBDAV TESTS ==== " @echo run-davtest: $(AM_V_at)if [ -z $(CADAVER) ]; then \ echo "SKIPPED - cadaver is required to run these tests"; \ else \ echo "davtest"; \ cd @srcdir@ && ./davtest ./davtest.in @abs_builddir@/logs/davtest.out;\ err=$$?; \ if test $$err -ne 0; then \ $(MAKE) quiet-stop; \ exit $$err; \ fi \ fi prepare-test:: $(AM_V_at)echo "test" > ./docroot-test/test # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t8/davtest0000775000175000017500000000046012605311413012327 00000000000000#!/bin/sh # # input=$1 output=$2 cadaver http://localhost:8000 < $input > $output success=`grep -c succeeded. $output` if [ $success -ne 9 ]; then echo "- not all cadaver actions succeeded, see $output for details" exit 1 fi printf "\n** All "`pwd`" tests completed successfully.\n\n" exit 0 yaws-2.0.2/test/t8/yaws.conf.in0000664000175000017500000000102412605311413013163 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 port = 8000 listen = 0.0.0.0 docroot = @abs_builddir@/docroot-test dav = true yaws-2.0.2/test/t8/davtest.in0000664000175000017500000000024612605311413012733 00000000000000unset tolerant set namespace DAV: ls propnames test put davtest.in rm davtest.in mkcol locked lock locked cd locked put davtest.in cd .. unlock locked rmcol locked yaws-2.0.2/test/t8/Makefile.am0000664000175000017500000000136012605311413012763 00000000000000EXTRA_DIST = davtest davtest.in include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test check-local: $(EBIN_FILES) log start wait-started run-davtest stop wait-stopped log: @echo @echo " ==== WEBDAV TESTS ==== " @echo run-davtest: $(AM_V_at)if [ -z $(CADAVER) ]; then \ echo "SKIPPED - cadaver is required to run these tests"; \ else \ echo "davtest"; \ cd @srcdir@ && ./davtest ./davtest.in @abs_builddir@/logs/davtest.out;\ err=$$?; \ if test $$err -ne 0; then \ $(MAKE) quiet-stop; \ exit $$err; \ fi \ fi prepare-test:: $(AM_V_at)echo "test" > ./docroot-test/test # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/eunit/0000775000175000017500000000000012605312014011576 500000000000000yaws-2.0.2/test/eunit/Makefile.in0000664000175000017500000003660412605311446013604 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/eunit DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = multipart_post_parsing.erl \ yaws_session_server_test.erl \ ehtml_test.erl \ cookies.erl \ headers.erl \ ipmask.erl \ gconf.erl \ sconf.erl \ yaws_rpc_test.erl \ proc_cleanup.erl \ subconfig.erl \ copy_error_log.erl EXTRA_DIST = $(MODULES) cookies.dump setcookies.dump subconfig_DATA EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) ERL_FLAGS = $(ERL_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/eunit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/eunit/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) client.log check-local: $(EBIN_FILES) $(top_builddir)/test/src/test.beam quiet-stop wait-stopped @echo @echo " ==== EUNIT TESTS ==== " @echo $(AM_V_at)$(ERL) $(ERL_GENERIC_FLAGS) -noshell -s test run $(MODULES:.erl=) distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/eunit/yaws_session_server_test.erl0000664000175000017500000001436512605311413017410 00000000000000-module (yaws_session_server_test). -include_lib("eunit/include/eunit.hrl"). -include("tftest.hrl"). -export ([mock_session_server/0]). %% Our test backend exports -export ([init_backend/1, stop_backend/0, insert/1, list/0, lookup/1, delete/1, traverse/1, cleanup/0]). %% Change this macro to test another backend storage module %%-define(BACKEND, ?MODULE). -define(BACKEND, yaws_session_server). start() -> %% starting crypto is required for these tests to pass on R13 application:start(crypto), application:load(yaws), Result = gen_server:start({local, yaws_session_server}, yaws_session_server, ?BACKEND, []), ?BACKEND:cleanup(), Result. init_test() -> {ok, _} = start(), ?assertEqual([], ?BACKEND:list()), yaws_session_server:stop(). new_session_and_list_test() -> {ok, _} = start(), ?assertMatch([], ?BACKEND:list()), Cookie1 = yaws_session_server:new_session({opaque, 1}), Cookie2 = yaws_session_server:new_session({opaque, 2}, 1, self()), Cookie3 = yaws_session_server:new_session({opaque, 3}, 1, self(), "cookie"), ?assert(Cookie1 /= Cookie2), "nonode@nohost-" ++ _ = Cookie1, "nonode@nohost-" ++ _ = Cookie2, "cookie" = Cookie3, ?assertMatch([_, _, _], ?BACKEND:list()), yaws_session_server:stop(). replace_session_test() -> {ok, _} = start(), Opaque = {opaque, 1}, Cookie1 = yaws_session_server:new_session(Opaque), [Session] = ?BACKEND:list(), Opaque2 = {opaque, 2}, true = yaws_session_server:replace_session(Cookie1, Opaque2), [Session_updated] = ?BACKEND:list(), ?assert(Session /= Session_updated), yaws_session_server:stop(). replace_session_cleanup_test() -> Parent = self(), Cleanup1 = spawn(fun() -> receive stop -> ok; Msg -> Parent ! {cleanup1, Msg} end end), {ok, _} = start(), Opaque = {opaque, 1}, Cookie = yaws_session_server:new_session(Opaque, 60, Cleanup1), Cleanup2 = spawn(fun() -> receive stop -> ok; Msg -> Parent ! {cleanup2, Msg} end end), Opaque2 = {opaque, 2}, true = yaws_session_server:replace_session(Cookie, Opaque2, Cleanup2), yaws_session_server:delete_session(Cookie), receive {cleanup2, {yaws_session_end, normal, _, Opaque2}} -> Cleanup1 ! stop, yaws_session_server:stop() after 5000 -> exit({error, cleanup_failure}) end. cookieval_to_opaque_test() -> {ok, _} = start(), Opaque = {opaque, 1}, Cookie1 = yaws_session_server:new_session(Opaque), [Session] = ?BACKEND:list(), timer:sleep(1000), %% ensure cookie TS is updated of at least 1 second {ok, Result} = yaws_session_server:cookieval_to_opaque(Cookie1), ?assertEqual(Opaque, Result), [Session_updated] = ?BACKEND:list(), ?assert(Session /= Session_updated), yaws_session_server:stop(). delete_session_test() -> {ok, _} = start(), Opaque = {opaque, 1}, Cookie1 = yaws_session_server:new_session(Opaque), Cookie2 = yaws_session_server:new_session(Opaque, 10, self()), [_, _] = ?BACKEND:list(), Expected1 = nocleanup, ?assertEqual(Expected1, yaws_session_server:delete_session(Cookie1)), Delete_notif = {yaws_session_end,normal,Cookie2,Opaque}, ?assertEqual(Delete_notif, yaws_session_server:delete_session(Cookie2)), [] = ?BACKEND:list(), receive Delete_notif -> ok after 500 -> exit (cleanup_timeout) end, yaws_session_server:stop(). timeout_test () -> {ok, Pid} = start(), Opaque = {opaque, 1}, Cookie1 = yaws_session_server:new_session(Opaque, 0, self()), Opaque2 = {opaque, 1}, _Cookie2 = yaws_session_server:new_session(Opaque2, 10, self()), ?assertMatch([_, _], ?BACKEND:list()), Pid ! timeout, Timeout_notif = {yaws_session_end,timeout,Cookie1,Opaque}, receive Timeout_notif -> ok after 500 -> exit (cleanup_timeout) end, ?assertMatch([_], ?BACKEND:list()), yaws_session_server:stop(). %% Our test callbacks init_backend(_) -> proc_lib:start (?MODULE, mock_session_server, []), ok. insert(Session) -> ?MODULE ! {insert, Session}, true. lookup(Cookie) -> ?MODULE ! {{lookup, Cookie}, self()}, receive {ok, Opaque} -> [Opaque] after 1000 -> list_timeout end. list() -> ?MODULE ! {list, self()}, receive {ok, Sessions} -> Sessions after 1000 -> list_timeout end. delete(Cookie) -> ?MODULE ! {delete, Cookie}, true. cleanup() -> Cleaner = fun(Session) -> Cookie = yaws_session_server:cookie(Session), delete(Cookie) end, lists:foreach(Cleaner, list()). traverse(Gnow) -> Timeouter = fun (Session) -> case yaws_session_server:has_timedout(Session, Gnow) of false -> ok; true -> yaws_session_server:report_timedout_sess(Session), Cookie = yaws_session_server:cookie(Session), delete(Cookie) end end, lists:foreach(Timeouter, list()). stop_backend() -> ?MODULE ! stop, ok. %% Mock Internals mock_session_server() -> register(?MODULE, self()), proc_lib:init_ack({ok, self()}), mock_loop(). mock_loop() -> receive {list, Pid} -> Pid ! {ok, sessions()}, mock_loop(); {insert, Session} -> Cookie = element(2, Session), put({session, Cookie}, Session), mock_loop(); {{lookup, Cookie}, Pid} -> Session = get({session, Cookie}), Pid ! {ok, Session}, mock_loop(); {delete, Cookie} -> erase({session, Cookie}), mock_loop(); stop -> ok; Other -> ?debugFmt("Unexpected: ~p~n", [Other]) end. sessions() -> lists:foldl(fun({{session, _}, Session}, Acc) -> [Session | Acc]; (_, Acc) -> Acc end, [], get()). yaws-2.0.2/test/eunit/subconfig_DATA/0000775000175000017500000000000012605311456014357 500000000000000yaws-2.0.2/test/eunit/subconfig_DATA/yaws_relative_no_wildcard.conf0000664000175000017500000000013712605311413022363 00000000000000subconfigdir = global_subconfigdir.d subconfig = global_relative_no_wildcard_subconfig.conf yaws-2.0.2/test/eunit/subconfig_DATA/yaws_absolute_no_wildcard.conf0000664000175000017500000000027112605311456022374 00000000000000subconfigdir = /home/klacke/yaws/test/eunit//subconfig_DATA/global_subconfigdir.d subconfig = /home/klacke/yaws/test/eunit//subconfig_DATA/global_absolute_no_wildcard_subconfig.conf yaws-2.0.2/test/eunit/subconfig_DATA/global_absolute_no_wildcard_subconfig.conf.in0000664000175000017500000000034012605311413025303 00000000000000 port = 8000 listen = 0.0.0.0 docroot = /tmp subconfigdir = @abs_srcdir@/server_subconfigdir.d subconfig = @abs_srcdir@/server_subconfig.conf yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfig.conf0000664000175000017500000000003712605311413020504 00000000000000serveralias = server_subconfig yaws-2.0.2/test/eunit/subconfig_DATA/yaws_absolute.conf0000664000175000017500000000040312605311456020024 00000000000000subconfigdir = /home/klacke/yaws/test/eunit//subconfig_DATA/global_subconfigdir.d subconfig = /home/klacke/yaws/test/eunit//subconfig_DATA/global_absolute_subconfig.conf subconfig = /home/klacke/yaws/test/eunit//subconfig_DATA/global_subconfig.d/*.conf yaws-2.0.2/test/eunit/subconfig_DATA/yaws_server_subconfig_notfound3.conf0000664000175000017500000000024312605311413023545 00000000000000 port = 8000 listen = 0.0.0.0 docroot = /tmp subconfigdir = /notfound/server_subconfig.conf yaws-2.0.2/test/eunit/subconfig_DATA/global_relative_no_wildcard_subconfig.conf0000664000175000017500000000030612605311413024675 00000000000000 port = 8000 listen = 0.0.0.0 docroot = /tmp subconfigdir = server_subconfigdir.d subconfig = server_subconfig.conf yaws-2.0.2/test/eunit/subconfig_DATA/yaws_global_subconfig_notfound3.conf0000664000175000017500000000005712605311413023502 00000000000000subconfigdir = /notfound/global_subconfig.conf yaws-2.0.2/test/eunit/subconfig_DATA/yaws_absolute.conf.in0000664000175000017500000000024512605311413020426 00000000000000subconfigdir = @abs_srcdir@/global_subconfigdir.d subconfig = @abs_builddir@/global_absolute_subconfig.conf subconfig = @abs_srcdir@/global_subconfig.d/*.conf yaws-2.0.2/test/eunit/subconfig_DATA/yaws_absolute_no_wildcard.conf.in0000664000175000017500000000017312605311413022773 00000000000000subconfigdir = @abs_srcdir@/global_subconfigdir.d subconfig = @abs_builddir@/global_absolute_no_wildcard_subconfig.conf yaws-2.0.2/test/eunit/subconfig_DATA/yaws_global_subconfig_notfound2.conf0000664000175000017500000000005312605311413023475 00000000000000subconfig = global_subconfig_notfound.conf yaws-2.0.2/test/eunit/subconfig_DATA/yaws_server_subconfig_notfound2.conf0000664000175000017500000000023712605311413023547 00000000000000 port = 8000 listen = 0.0.0.0 docroot = /tmp subconfig = server_subconfig_notfound.conf yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfig.d/0000775000175000017500000000000012605311413020137 500000000000000yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfig.d/subconfig2.conf0000664000175000017500000000004012605311413022761 00000000000000serveralias = server_subconfig2 yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfig.d/subconfig1.conf0000664000175000017500000000004012605311413022760 00000000000000serveralias = server_subconfig1 yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfig.d/.hidden.conf0000664000175000017500000000002612605311413022235 00000000000000invalid_param = error yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfig.d/ignored0000664000175000017500000000002612605311413021427 00000000000000invalid_param = error yaws-2.0.2/test/eunit/subconfig_DATA/global_absolute_subconfig.conf0000664000175000017500000000057612605311456022353 00000000000000 port = 8000 listen = 0.0.0.0 docroot = /tmp subconfigdir = /home/klacke/yaws/test/eunit//subconfig_DATA/server_subconfigdir.d subconfig = /home/klacke/yaws/test/eunit//subconfig_DATA/server_subconfig.conf subconfig = /home/klacke/yaws/test/eunit//subconfig_DATA/server_subconfig.d/*.conf yaws-2.0.2/test/eunit/subconfig_DATA/global_relative_subconfig.conf0000664000175000017500000000036712605311413022337 00000000000000 port = 8000 listen = 0.0.0.0 docroot = /tmp subconfigdir = server_subconfigdir.d subconfig = server_subconfig.conf subconfig = server_subconfig.d/*.conf yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfigdir.d/0000775000175000017500000000000012605311413020636 500000000000000yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfigdir.d/subconfigdir1.conf0000664000175000017500000000004312605311413024161 00000000000000serveralias = server_subconfigdir1 yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfigdir.d/subconfigdir2.conf0000664000175000017500000000004312605311413024162 00000000000000serveralias = server_subconfigdir2 yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfigdir.d/.hidden.conf0000664000175000017500000000002612605311413022734 00000000000000invalid_param = error yaws-2.0.2/test/eunit/subconfig_DATA/yaws_server_subconfig_notfound1.conf0000664000175000017500000000024412605311413023544 00000000000000 port = 8000 listen = 0.0.0.0 docroot = /tmp subconfig = /tmp/server_subconfig_notfound.conf yaws-2.0.2/test/eunit/subconfig_DATA/global_subconfigdir.d/0000775000175000017500000000000012605311413020570 500000000000000yaws-2.0.2/test/eunit/subconfig_DATA/global_subconfigdir.d/subconfigdir1.conf0000664000175000017500000000015312605311413024115 00000000000000 port = 8003 listen = 0.0.0.0 docroot = /tmp yaws-2.0.2/test/eunit/subconfig_DATA/global_subconfigdir.d/subconfigdir2.conf0000664000175000017500000000015312605311413024116 00000000000000 port = 8004 listen = 0.0.0.0 docroot = /tmp yaws-2.0.2/test/eunit/subconfig_DATA/global_subconfigdir.d/.hidden.conf0000664000175000017500000000002612605311413022666 00000000000000invalid_param = error yaws-2.0.2/test/eunit/subconfig_DATA/yaws_global_subconfig_notfound1.conf0000664000175000017500000000006012605311413023472 00000000000000subconfig = /tmp/global_subconfig_notfound.conf yaws-2.0.2/test/eunit/subconfig_DATA/yaws_relative.conf0000664000175000017500000000017412605311413020017 00000000000000subconfigdir = global_subconfigdir.d subconfig = global_relative_subconfig.conf subconfig = global_subconfig.d/*.conf yaws-2.0.2/test/eunit/subconfig_DATA/server_subconfig_closing_tag.conf0000664000175000017500000000001212605311413023046 00000000000000
yaws-2.0.2/test/eunit/subconfig_DATA/global_absolute_no_wildcard_subconfig.conf0000664000175000017500000000044012605311456024706 00000000000000 port = 8000 listen = 0.0.0.0 docroot = /tmp subconfigdir = /home/klacke/yaws/test/eunit//subconfig_DATA/server_subconfigdir.d subconfig = /home/klacke/yaws/test/eunit//subconfig_DATA/server_subconfig.conf yaws-2.0.2/test/eunit/subconfig_DATA/global_subconfig.d/0000775000175000017500000000000012605311413020071 500000000000000yaws-2.0.2/test/eunit/subconfig_DATA/global_subconfig.d/subconfig2.conf0000664000175000017500000000015312605311413022720 00000000000000 port = 8002 listen = 0.0.0.0 docroot = /tmp yaws-2.0.2/test/eunit/subconfig_DATA/global_subconfig.d/subconfig1.conf0000664000175000017500000000015312605311413022717 00000000000000 port = 8001 listen = 0.0.0.0 docroot = /tmp yaws-2.0.2/test/eunit/subconfig_DATA/global_subconfig.d/.hidden.conf0000664000175000017500000000002612605311413022167 00000000000000invalid_param = error yaws-2.0.2/test/eunit/subconfig_DATA/global_subconfig.d/ignored0000664000175000017500000000002612605311413021361 00000000000000invalid_param = error yaws-2.0.2/test/eunit/subconfig_DATA/global_absolute_subconfig.conf.in0000664000175000017500000000043612605311413022744 00000000000000 port = 8000 listen = 0.0.0.0 docroot = /tmp subconfigdir = @abs_srcdir@/server_subconfigdir.d subconfig = @abs_srcdir@/server_subconfig.conf subconfig = @abs_srcdir@/server_subconfig.d/*.conf yaws-2.0.2/test/eunit/subconfig_DATA/yaws_server_subconfig_closing_tag.conf0000664000175000017500000000024212605311413024116 00000000000000 port = 8000 listen = 0.0.0.0 docroot = /tmp subconfig = server_subconfig_closing_tag.conf yaws-2.0.2/test/eunit/proc_cleanup.erl0000664000175000017500000000353012605311413014677 00000000000000-module(proc_cleanup). -author('kruber@zib.de'). -behaviour(supervisor). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). %% Explicitly export supervisor's callback because of a "bug" in R15/16 -export([init/1]). -include("yaws.hrl"). -include("tftest.hrl"). proc_cleanup_test() -> Old = get_processes(), process_flag(trap_exit, true), P = start_link(), erlang:exit(P, kill), timer:sleep(500), ?assertEqual([], [Proc || Proc <- get_processes(), not lists:member(Proc, Old)]), ok. start_link() -> Id = "yaws", Docroot = ".", GconfList = [{id, Id}], SconfList = [{docroot, Docroot}], %% load yaws application (required by yaws_api:embedded_start_conf) ok = application:unload(yaws), ok = application:load( {application, yaws, [{description, "yaws WWW server"}, {vsn, "1.98"}, {modules, []}, {registered, []}, {mod, {yaws_app, []}}, {env, []}, {applications, [kernel, stdlib]}]}), {ok, SCList, GC, ChildSpecs} = yaws_api:embedded_start_conf(Docroot, SconfList, GconfList, Id), {ok, Pid} = supervisor:start_link(?MODULE, ChildSpecs), %% now configure Yaws ok = yaws_api:setconf(GC, SCList), Pid. init(ChildSpecs) -> {ok, {{one_for_all, 10, 1}, ChildSpecs}}. get_processes() -> [begin InitCall = case proc_lib:initial_call(X) of false -> element(2, lists:keyfind(initial_call, 1, Data)); {Module, Function, Args} -> {Module, Function, length(Args)} end, CurFun = element(2, lists:keyfind(current_function, 1, Data)), {X, InitCall, CurFun} end || X <- processes(), Data <- [process_info(X, [current_function, initial_call, registered_name])], Data =/= undefined]. yaws-2.0.2/test/eunit/ehtml_test.erl0000664000175000017500000000641412605311413014401 00000000000000-module(ehtml_test). -include_lib("eunit/include/eunit.hrl"). -include("tftest.hrl"). -export([mfa_fun/1, nested_mfa_fun/1, nested_mfa_attr_fun/1]). void_element_test() -> %% No end tag () for void elements in HTML5. {ehtml, E1} = {ehtml, [{img, [{src, "foo.png"}, {alt, "foo"}]}]}, Img = "\"foo\"", Img = lists:flatten(yaws_api:ehtml_expand(E1)), {ehtml, E2} = {ehtml, [{br}]}, Br = "
", Br = lists:flatten(yaws_api:ehtml_expand(E2)). non_void_element_test() -> %% No self-closing syntax (/>) for non-void elements in HTML5. {ehtml, E} = {ehtml, [{p}]}, P = "

", P = lists:flatten(yaws_api:ehtml_expand(E)). attributes_test() -> {ehtml, E1} = {ehtml, [{img, [{check, src, <<"quote\".png">>}, {check, width, 10}, {height, 20}, {check, alt, "quote\""}]}]}, Img = <<"quote\"">>, Img = iolist_to_binary(yaws_api:ehtml_expand(E1)), {ehtml, E2} = {ehtml, [{a, [{href, <<"test">>}], <<"test link">>}]}, A = <<"test link">>, A = iolist_to_binary(yaws_api:ehtml_expand(E2)). get_title() -> "Funtest Title". simple_fun_test() -> {ehtml, E} = {ehtml, [{title, [], fun get_title/0}]}, Title = "\n" ++ get_title() ++ "", Title = lists:flatten(yaws_api:ehtml_expand(E)). mfa_fun(Args) -> Args. mfa_test() -> Args = ["another ", "string"], {ehtml, E} = {ehtml, [{p, [], {?MODULE, mfa_fun, Args}}]}, P = lists:flatten(["\n

", Args, "

"]), P = lists:flatten(yaws_api:ehtml_expand(E)). nested_fun_test() -> Value = "paragraph", {ehtml, E} = {ehtml, [fun() -> [{p, [], Value}] end]}, P = lists:flatten(["\n

", Value, "

"]), P = lists:flatten(yaws_api:ehtml_expand(E)). nested_mfa_fun(Args) -> fun() -> [{p, [], fun() -> Args end}] end. nested_mfa_test() -> Args = ["another ", "string"], {ehtml, E} = {ehtml, [{?MODULE, nested_mfa_fun, Args}]}, P = lists:flatten(["\n

", Args, "

"]), P = lists:flatten(yaws_api:ehtml_expand(E)). get_link() -> "http://yaws.hyber.org/". simple_attr_test() -> Link = "link", {ehtml, E} = {ehtml, [{a, [{href, fun get_link/0}], Link}]}, A = lists:flatten(["", Link, ""]), A = lists:flatten(yaws_api:ehtml_expand(E)). mfa_attr_test() -> Args = [get_link()], Link = "link", {ehtml, E} = {ehtml, [{a, [{href, {?MODULE, mfa_fun, Args}}], Link}]}, A = lists:flatten(["", Link, ""]), A = lists:flatten(yaws_api:ehtml_expand(E)). nested_attr_test() -> Link = "link", {ehtml, E} = {ehtml, [{a, [{href, fun() -> fun get_link/0 end}], Link}]}, A = lists:flatten(["", Link, ""]), A = lists:flatten(yaws_api:ehtml_expand(E)). nested_mfa_attr_fun(Args) -> {?MODULE, mfa_fun, Args}. nested_mfa_attr_test() -> Args = [get_link()], Link = "link", {ehtml, E} = {ehtml, [{a, [{href, {?MODULE, nested_mfa_attr_fun, Args}}], Link}]}, A = lists:flatten(["", Link, ""]), A = lists:flatten(yaws_api:ehtml_expand(E)). yaws-2.0.2/test/eunit/headers.erl0000664000175000017500000000766212605311413013652 00000000000000-module(headers). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). -include("yaws_api.hrl"). -include("tftest.hrl"). set_headers_test() -> Value = "test value", lists:foreach(fun({Hdr, StrHdr, Fun}) -> NewHdrs = yaws_api:set_header(#headers{}, Hdr, Value), Value = yaws_api:Fun(NewHdrs), Value = yaws_api:get_header(NewHdrs, StrHdr), 0 = length(NewHdrs#headers.other) end, field_headers()), Hdrs = yaws_api:set_header(create_headers(99), age, "123"), 100 = length(Hdrs#headers.other), ok. get_headers_test() -> undefined = yaws_api:get_header(#headers{}, accept), undefined = yaws_api:get_header(#headers{}, "Connection"), none = yaws_api:get_header(#headers{}, range, none), none = yaws_api:get_header(#headers{}, "No-Such-Header", none), Hdrs = create_headers(100), lists:foreach(fun(I) -> L = integer_to_list(I), Val = "value"++L, Hdr = "X-HEADER-"++L, Val = yaws_api:get_header(Hdrs, Hdr) end, lists:seq(1,100)), ok. delete_headers_test() -> Headers = create_headers(10), {0, #headers{}} = lists:foldl( fun(I, {Size, Hdrs}) -> Size = length(Hdrs#headers.other), L = integer_to_list(I), Hdr = "X-Header-"++L, NHdrs = yaws_api:delete_header(Hdrs, Hdr), NewSize = Size - 1, NewSize = length(NHdrs#headers.other), {NewSize, NHdrs} end, {10, Headers}, lists:seq(1,10)), ok. merge_headers_test() -> Hdrs0 = create_headers(10), Hdrs1 = yaws_api:merge_header(Hdrs0, <<"x-header-7">>, <<"another-value">>), Val1 = yaws_api:get_header(Hdrs1, 'x-header-7'), Expected1 = lists:sort(["value7", "another-value"]), Expected1 = lists:sort(string:tokens(Val1, ", ")), Hdrs2 = yaws_api:set_header(Hdrs1, "set-cookie", "user=joe"), Hdrs3 = yaws_api:merge_header(Hdrs2, "set-cookie", "domain=erlang.org"), Val2 = yaws_api:get_header(Hdrs3, "set-cookie"), {multi, ["user=joe", "domain=erlang.org"]} = Val2, ok. create_headers(N) -> lists:foldl(fun({Hdr,Val}, Hdrs) -> yaws_api:set_header(Hdrs, Hdr, Val) end, #headers{}, [begin L = integer_to_list(I), {"X-Header-"++L, "value"++L} end || I <- lists:seq(1,N)]). %% these headers are the fields in the #headers{} record field_headers() -> [{connection, "Connection", headers_connection}, {accept, "Accept", headers_accept}, {host, "Host", headers_host}, {if_modified_since,"If-Modified-Since", headers_if_modified_since}, {if_match, "If-Match", headers_if_match}, {if_none_match, "If-None-Match", headers_if_none_match}, {if_range, "if-Range", headers_if_range}, {if_unmodified_since, "If-Unmodified-Since", headers_if_unmodified_since}, {range, "Range", headers_range}, {referer, "Referer", headers_referer}, {user_agent, "User-Agent", headers_user_agent}, {accept_ranges, "Accept-Ranges", headers_accept_ranges}, {cookie, "Cookie", headers_cookie}, {keep_alive, "Keep-Alive", headers_keep_alive}, {location, "Location", headers_location}, {content_length, "Content-Length", headers_content_length}, {content_type, "Content-Type", headers_content_type}, {content_encoding, "Content-Encoding", headers_content_encoding}, {authorization, "Authorization", headers_authorization}, {transfer_encoding, "Transfer-Encoding", headers_transfer_encoding}, {x_forwarded_for, "X-Forwarded-For", headers_x_forwarded_for}]. yaws-2.0.2/test/eunit/sconf.erl0000664000175000017500000002161512605311413013341 00000000000000-module(sconf). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). -include("yaws.hrl"). -include("tftest.hrl"). setup_default_sconf_test() -> Dir = filename:absname("."), SC1 = yaws_config:make_default_sconf(".", undefined), SC1 = yaws:create_sconf(".", []), {docroot, Dir} = get_sconf_attr(docroot, SC1), {listen, {127,0,0,1}} = get_sconf_attr(listen, SC1), {port, 8000} = get_sconf_attr(port, SC1), SC2 = yaws_config:make_default_sconf(".", 8080), SC2 = yaws:create_sconf(".", [{port, 8080}]), {port, 8080} = get_sconf_attr(port, SC2), ok. set_sc_flags_test() -> SC = yaws:create_sconf(".", []), {access_log, true} = check_sc_flags(access_log, ?SC_ACCESS_LOG, SC), {auth_log, true} = check_sc_flags(auth_log, ?SC_AUTH_LOG, SC), {add_port, true} = check_sc_flags(add_port, ?SC_ADD_PORT, SC), {statistics, true} = check_sc_flags(statistics, ?SC_STATISTICS, SC), {tilde_expand, true} = check_sc_flags(tilde_expand, ?SC_TILDE_EXPAND, SC), {dir_listings, true} = check_sc_flags(dir_listings, ?SC_DIR_LISTINGS, SC), {deflate, true} = check_sc_flags(deflate, ?SC_DEFLATE, SC), {dir_all_zip, true} = check_sc_flags(dir_all_zip, ?SC_DIR_ALL_ZIP, SC), {dav, true} = check_sc_flags(dav, ?SC_DAV, SC), {fcgi_trace_protocol, true} = check_sc_flags(fcgi_trace_protocol, ?SC_FCGI_TRACE_PROTOCOL, SC), {fcgi_log_app_error, true} = check_sc_flags(fcgi_log_app_error, ?SC_FCGI_LOG_APP_ERROR, SC), {forward_proxy, true} = check_sc_flags(forward_proxy, ?SC_FORWARD_PROXY, SC), {auth_skip_docroot, true} = check_sc_flags(auth_skip_docroot, ?SC_AUTH_SKIP_DOCROOT, SC), ok. setup_ssl_test() -> SC0 = yaws:create_sconf(".", []), undefined = yaws:sconf_ssl(SC0), SC1 = yaws:create_sconf(".", [{ssl, []}]), SSL1 = yaws:new_ssl(), SSL1 = yaws:sconf_ssl(SC1), SSL2 = yaws:ssl_keyfile(SSL1, "/tmp/yaws-key.pem"), SC2 = yaws:create_sconf(".", [{ssl, SSL2}]), "/tmp/yaws-key.pem" = yaws:ssl_keyfile( yaws:sconf_ssl(SC2) ), PVs = ['tlsv1.2', 'tlsv1.1', tlsv1], SC3 = yaws:create_sconf(".", [{ssl, [{protocol_version, PVs}]}]), ?assertMatch(#ssl{protocol_version=PVs}, yaws:sconf_ssl(SC3)), ok. setup_authdirs_test() -> SC0 = yaws:create_sconf(".", []), [] = yaws:sconf_authdirs(SC0), SC1 = yaws:create_sconf(".", [{auth, []}]), Auth1 = yaws:new_auth(), [Auth1] = yaws:sconf_authdirs(SC1), Auth2 = yaws:auth_dir(Auth1, "/"), SC2 = yaws:create_sconf(".", [{auth, Auth2}]), "/" = yaws:auth_dir( hd(yaws:sconf_authdirs(SC2)) ), ok. setup_deflate_test() -> SC0 = yaws:create_sconf(".", []), undefined = yaws:sconf_deflate_options(SC0), SC1 = yaws:create_sconf(".", [{deflate_options, []}]), DOpts1 = yaws:new_deflate(), DOpts1 = yaws:sconf_deflate_options(SC1), DOpts2 = yaws:deflate_compression_level(DOpts1, best_speed), SC2 = yaws:create_sconf(".", [{deflate_options, DOpts2}]), best_speed = yaws:deflate_compression_level( yaws:sconf_deflate_options(SC2) ), ok. setup_mime_types_info_test() -> SC0 = yaws:create_sconf(".", []), undefined = yaws:sconf_mime_types_info(SC0), SC1 = yaws:create_sconf(".", [{mime_types_info, []}]), MI1 = yaws:new_mime_types_info(), MI1 = yaws:sconf_mime_types_info(SC1), MI2 = yaws:mime_types_info_mime_types_file(MI1, "/etc/mime.types"), SC2 = yaws:create_sconf(".", [{mime_types_info, MI2}]), "/etc/mime.types" = yaws:mime_types_info_mime_types_file( yaws:sconf_mime_types_info(SC2) ), ok. comp_sname_test() -> ?assert(yaws_server:comp_sname("yaws.hyber.org", "yaws.hyber.org")), ?assert(yaws_server:comp_sname("yaws.hyber.org", "YAWS.HYBER.ORG")), ?assert(yaws_server:comp_sname("yaws.hyber.org:80", "yaws.hyber.org")), ?assert(yaws_server:comp_sname("yaws.hyber.org", "yaws.hyber.org:80")), ?assert(yaws_server:comp_sname("yaws.hyber.org:443", "yaws.hyber.org:80")), ?assertNot(yaws_server:comp_sname("yaws.hyber.org", "yaws.hyber.com")), ?assertNot(yaws_server:comp_sname("yaws.hyber.org:80", "yaws.hyber.org.bad")), ?assertNot(yaws_server:comp_sname("yaws.hyber.org.bad", "yaws.hyber.org:80")), ?assertNot(yaws_server:comp_sname("yaws.hyber.org", "yaws.hyber.org.bad")), ?assertNot(yaws_server:comp_sname("yaws.hyber.org.bad", "yaws.hyber.org")), ok. wildcomp_salias_test() -> ?assert(yaws_server:wildcomp_salias("yaws.hyber.org", "yaws.hyber.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org", "YAWS.HYBER.ORG")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org:80", "yaws.hyber.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org", "yaws.hyber.org:80")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org:443", "yaws.hyber.org:80")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.org", "yaws.hyber.com")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.org:80", "yaws.hyber.org.bad")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.org.bad", "yaws.hyber.org:80")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.org", "yaws.hyber.org.bad")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.org.bad", "yaws.hyber.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org", "*.hyber.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.hyber.org", "*.hyber.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org", "yaws.*.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.hyber.org", "yaws.*.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org.org", "yaws.*.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org", "yaws.hyber.*")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.hyber.org", "yaws.hyber.*")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org.org", "yaws.hyber.*")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org", "*.hyber.*")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.hyber.org", "*.hyber.*")), ?assert(yaws_server:wildcomp_salias("erlang.hyber.org", "*.hyber.*")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org", "*.*.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.hyber.org", "*.*.org")), ?assert(yaws_server:wildcomp_salias("..org", "*.*.org")), ?assert(yaws_server:wildcomp_salias("hyber.org", "*hyber.org")), ?assert(yaws_server:wildcomp_salias("yaws-hyber.org", "*hyber.org")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.com", "*.hyber.org")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.hyber.com", "*.hyber.org")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.org.org", "*.hyber.org")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.org.com", "*.hyber.org")), ?assertNot(yaws_server:wildcomp_salias("erlang.hyber.org", "yaws.*.org")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.com", "yaws.*.org")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.hyber.com", "yaws.*.org")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.org.com", "yaws.*.org")), ?assertNot(yaws_server:wildcomp_salias("erlang.hyber.com", "yaws.hyber.*")), ?assertNot(yaws_server:wildcomp_salias("yaws.yaws.hyber.org", "yaws.hyber.*")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org", "?aws.hyber.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.org", "????.hyber.org")), ?assert(yaws_server:wildcomp_salias("yaws-hyber.org", "yaws?hyber.org")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.com", "?aws.hyber.org")), ?assertNot(yaws_server:wildcomp_salias("yaw.hyber.org", "????.hyber.org")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.org", "???.hyber.org")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.org", "yaws?hyber.org")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.hyber.org", "yaws.*.hyber.???")), ?assert(yaws_server:wildcomp_salias("yaws.hyber.hyber.com", "yaws.*.hyber.???")), ?assertNot(yaws_server:wildcomp_salias("yaws.hyber.hyber.fr", "yaws.*.hyber.???")), ok. %% ======================================================================= get_sconf_attr(Name, SConf) -> Fun = list_to_atom("sconf_" ++ atom_to_list(Name)), {Name, yaws:Fun(SConf)}. check_sc_flags(Flag, Id, SConf0) -> Flags0 = yaws:sconf_flags(SConf0), Val0 = (Flags0 band Id) /= 0, SConf1 = yaws:create_sconf(".", [{flags, [{Flag, not Val0}]}]), Flags1 = yaws:sconf_flags(SConf1), Flags2 = yaws:flag(Flags1, Id, Val0), {Flag, (not Val0 == ((Flags1 band Id) /= 0) andalso Flags2 == Flags0)}. yaws-2.0.2/test/eunit/yaws_rpc_test.erl0000664000175000017500000000114012605311413015106 00000000000000%% coding: utf-8 -module(yaws_rpc_test). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). -include("yaws_api.hrl"). -include("tftest.hrl"). -define(PARAMS, ["åäö","abc"]). %% ignore it unicode_test() -> Payload = json2:encode({struct,[{method,"foo"},{id,"id"}, {params,?PARAMS}]}), Req = #http_request{method='POST', version={1,1}}, Hdrs = #headers{}, Arg = #arg{clidata=Payload,req=Req,headers=Hdrs}, yaws_rpc:handler(Arg, {?MODULE, handler}), timer:sleep(2000), ok. handler(_, {call,foo,{array,?PARAMS}}) -> false. yaws-2.0.2/test/eunit/subconfig.erl0000664000175000017500000001003212605311413014177 00000000000000-module(subconfig). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). -include("yaws.hrl"). -include("tftest.hrl"). bad_global_subconfig_test() -> Env1 = #env{debug = false, conf = {file, ?srcdir++"/subconfig_DATA/yaws_global_subconfig_notfound1.conf"}}, {error, _} = yaws_config:load(Env1), Env2 = #env{debug = false, conf = {file, ?srcdir++"/subconfig_DATA/yaws_global_subconfig_notfound2.conf"}}, {error, _} = yaws_config:load(Env2), Env3 = #env{debug = false, conf = {file, ?srcdir++"/subconfig_DATA/yaws_global_subconfig_notfound3.conf"}}, {error, _} = yaws_config:load(Env3), ok. bad_server_subconfig_test() -> Env1 = #env{debug = false, conf = {file, ?srcdir++"/subconfig_DATA/yaws_server_subconfig_notfound1.conf"}}, {error, _} = yaws_config:load(Env1), Env2 = #env{debug = false, conf = {file, ?srcdir++"/subconfig_DATA/yaws_server_subconfig_notfound2.conf"}}, {error, _} = yaws_config:load(Env2), Env3 = #env{debug = false, conf = {file, ?srcdir++"/subconfig_DATA/yaws_server_subconfig_notfound3.conf"}}, {error, _} = yaws_config:load(Env3), Env4 = #env{debug = false, conf = {file, ?srcdir++"/subconfig_DATA/yaws_server_subconfig_closing_tag.conf"}}, {error, _} = yaws_config:load(Env4), ok. -ifndef(HAVE_BAD_WILDCARD). absolute_subconfig_test() -> Env = #env{debug = false, conf = {file, ?builddir++"/subconfig_DATA/yaws_absolute.conf"}}, {ok, _GC, SCs} = yaws_config:load(Env), check_sconfs(lists:flatten(SCs)). relative_subconfig_test() -> Env = #env{debug = false, conf = {file, ?srcdir++"/subconfig_DATA/yaws_relative.conf"}}, {ok, _GC, SCs} = yaws_config:load(Env), check_sconfs(lists:flatten(SCs)). check_sconfs(SCs) -> ?assertEqual(5, length(SCs)), ?assert(lists:keymember(8000, #sconf.port, SCs)), ?assert(lists:keymember(8001, #sconf.port, SCs)), ?assert(lists:keymember(8002, #sconf.port, SCs)), ?assert(lists:keymember(8003, #sconf.port, SCs)), ?assert(lists:keymember(8004, #sconf.port, SCs)), SC_8000 = lists:keyfind(8000, #sconf.port, SCs), ?assertEqual(5, length(SC_8000#sconf.serveralias)), ?assert(lists:member("server_subconfig", SC_8000#sconf.serveralias)), ?assert(lists:member("server_subconfig1", SC_8000#sconf.serveralias)), ?assert(lists:member("server_subconfig2", SC_8000#sconf.serveralias)), ?assert(lists:member("server_subconfigdir1", SC_8000#sconf.serveralias)), ?assert(lists:member("server_subconfigdir2", SC_8000#sconf.serveralias)), ok. -else. absolute_subconfig_test() -> Env = #env{debug = false, conf = {file, ?builddir++"/subconfig_DATA/yaws_absolute_no_wildcard.conf"}}, {ok, _GC, SCs} = yaws_config:load(Env), check_sconfs(lists:flatten(SCs)). relative_subconfig_test() -> Env = #env{debug = false, conf = {file, ?srcdir++"/subconfig_DATA/yaws_relative_no_wildcard.conf"}}, {ok, _GC, SCs} = yaws_config:load(Env), check_sconfs(lists:flatten(SCs)). unsupported_wildcard_test() -> Env1 = #env{debug = false, conf = {file, ?builddir++"/subconfig_DATA/yaws_absolute.conf"}}, {error, _} = yaws_config:load(Env1), Env2 = #env{debug = false, conf = {file, ?srcdir++"/subconfig_DATA/yaws_relative.conf"}}, {error, _} = yaws_config:load(Env2), ok. check_sconfs(SCs) -> ?assertEqual(3, length(SCs)), ?assert(lists:keymember(8000, #sconf.port, SCs)), ?assert(lists:keymember(8003, #sconf.port, SCs)), ?assert(lists:keymember(8004, #sconf.port, SCs)), SC_8000 = lists:keyfind(8000, #sconf.port, SCs), ?assertEqual(3, length(SC_8000#sconf.serveralias)), ?assert(lists:member("server_subconfig", SC_8000#sconf.serveralias)), ?assert(lists:member("server_subconfigdir1", SC_8000#sconf.serveralias)), ?assert(lists:member("server_subconfigdir2", SC_8000#sconf.serveralias)), ok. -endif. yaws-2.0.2/test/eunit/setcookies.dump0000664000175000017500000006333112605311413014565 000000000000003_idz=4A%2FVxQ%2B0m1AlCavMdUmzFb9RGt1qWYceCgzWgJeT0QG5Ce8crypiNLNEElsYFHwBEuKEhoFZwBXjaXf9lKQ4k912Cu%2Bp6nJ9WPNVRlkFXNDuQVeBnpkkWQinDKUjpFNT41%2F9OcqmarsuZBWUVP6S699FeCW7; path=/ 3_idzlast=1341913429; expires=Thu, 10-Jul-2014 09:43:49 GMT; path=/ 3_idzp=%7B%22lastseen%22%3A0%2C%22site_id%22%3A3%2C%22chatcount%22%3A0%2C%22nbrVisite%22%3A0%2C%22ip%22%3A%2246.255.176.2%22%2C%22country%22%3Anull%2C%22country_name%22%3A%22%22%2C%22city%22%3A%22%22%2C%22lat%22%3Anull%2C%22long%22%3Anull%2C%22lang%22%3A%22fr%22%2C%22visitorname%22%3A%22+%22%2C%22extID%22%3Anull%2C%22pageview%22%3A1%2C%22connectionTime%22%3A1341913429%2C%22navTime%22%3A1000%2C%22actualURI%22%3A%22http%3A%5C%2F%5C%2Fwww.fnac.com%5C%2F%22%2C%22origin_site%22%3A%22%22%2C%22origin%22%3A%22direct%22%2C%22refengine%22%3A%22%22%2C%22refkeyword%22%3A%22%22%7D; path=/ 3_idz=QxQZv0%2FdKcoPFQz2soqlV99hxSRsrFzFCKoJl7yQNpF7ZfPA7stTFLFZekX%2Fg4ZwfqCa2UGu6PBt%2F%2BG7TYvUMcb9Szi09LcQlMGGNB1A2wPYbdjtIIQA5aKImYUDeh4sJFSQnGW76I9FTAKlFDNiqMAFGkfpmQoLi8oIpupzG02gyeavT4Cw5fq4q3h2m4%2FalA%3D%3D; path=/ 3vvc=1; expires=Thu, 10-Jul-2014 09:43:49 GMT; path=/ 68_idzlast=1341913412; expires=Thu, 10-Jul-2014 09:43:32 GMT; path=/ 68_idz=OibaSBYdlGwyj8aTbFGGgPYTNssFAMVioQ8owFaD2KIvHR94A6UIur57pIREK7EUmxv0ytkFcO1orjpoIvEMvCMwtVdIq9NEBz3Vvq%2Bc9%2BQM4J3k9L9XU0NCvZB8zUpHUq0Oe7g7dxSqpl7V0ePPpqsA3oG0eyj%2FeoIiANRjAkxImf2T%2F12kz2jHhpNfQ9%2BGPjk%3D; path=/ 68_idzp=%7B%22lastseen%22%3A0%2C%22site_id%22%3A68%2C%22chatcount%22%3A0%2C%22nbrVisite%22%3A0%2C%22ip%22%3A%2246.255.176.2%22%2C%22country%22%3Anull%2C%22country_name%22%3A%22%22%2C%22city%22%3A%22%22%2C%22lat%22%3Anull%2C%22long%22%3Anull%2C%22lang%22%3A%22fr%22%2C%22visitorname%22%3A%22+%22%2C%22extID%22%3Anull%2C%22pageview%22%3A1%2C%22connectionTime%22%3A1341913412%2C%22navTime%22%3A1000%2C%22actualURI%22%3A%22http%3A%5C%2F%5C%2Fwww.rueducommerce.fr%5C%2Fhome%5C%2Findex.htm%22%2C%22origin_site%22%3A%22%22%2C%22origin%22%3A%22direct%22%2C%22refengine%22%3A%22%22%2C%22refkeyword%22%3A%22%22%7D; path=/ 68_idz=Rp8OauLnfFEYqsY0FcfvxfMU3x8jstZQfIet8PDzo3xkP1reo9GH3wWadbRJGgcwYR%2BbAYJbM1SB2iue8UiNIPfVnjPOAndFl999m7fcHpYdopNLNPUlq64IOEy%2BTX%2Bts%2FdVWR0wp2rtnWQDNVejKQetQHnN; path=/ 68vvc=1; expires=Thu, 10-Jul-2014 09:43:32 GMT; path=/ a2=AAAAAA==; domain=atemda.com; expires=Sat, 08-Sep-2012 09:43:50 GMT; path=/ A3=BBKVd1h.0dqg00001APFTd1oO09TQ00000BaUid1h.0aok00001Bmhrd12d03Dp00000Bim0d1h.0erB00001Beysd1h.06kC00001BMXyd5wt0gtl00001B02ad1h.0dqe00002vVSid5wm0dqj00000; expires=Mon, 08-Oct-2012 05:49:54 GMT; domain=.serving-sys.com; path=/ AA002=1341913385-22335145; expires=Thursday, 10-Jul-2014 00:00:00 GMT; path=/; domain=.atdmt.com a=c638666722680058483;Path=/;Domain=.rfihub.com;Expires=Sat, 27-Dec-14 09:49:56 GMT ACID=rR040013419137810010; domain=advertising.com; expires=Thu, 10-Jul-2014 09:49:41 GMT; path=/ ACT=1; domain=.fnac.com; expires=Sun, 09-Jul-2017 09:44:07 GMT; path=/ ad-id=A0JZ6M3ZekHSo82QrcyzOyQ; Domain=.amazon-adsystem.com; Expires=Thu, 01-Jan-2037 00:00:01 GMT; Path=/ _adpc=CrbTHaab; domain=.sfr.solution.weborama.fr; path=/; expires=Sun, 09-Sep-2012 00:04:45 GMT _adppdiffc_z=eJxlybENACAQAsCFMIGHVxP338vGzvauqOISj93GEJykIFEbxPPM5jcXWKULeA%3D%3D; domain=.aimfar.solution.weborama.fr; path=/; expires=Sat, 08-Sep-2012 09:43:29 GMT _advcrea=bbX|bQ7.bRR|a:cb; domain=.sfr.solution.weborama.fr; path=/; expires=Fri, 19-Oct-2012 08:51:23 GMT afpperso=nav2012=oldnav&tcp=ok34; expires=Thu, 07-Jul-2022 22:00:00 GMT; domain=aufeminin.com; path=/ aisakosId=292a5f46-3010-4a63-88f4-3bce157b746c;Version=0;Comment=aisakosId;Domain=ezakus.net;Path=/;Max-Age=63072000;expires=Thu, 10 Jul 2014 09:43:23 GMT; anj=Kfu=8fG5+^Cxrx)0s]#%2L_'x%SEV/hnK]14FV*PP2>D/kb10I$)L<2etI]'_2pvH'*a'xv:V@/d!5$(9KzOiAmx@5sh78I)HHN/; path=/; expires=Mon, 08-Oct-2012 09:49:48 GMT; domain=.adnxs.com; HttpOnly anj=Kfu=8fG68%Cxrx)0s]#%2L_'x%SEV/hnJPh4FV*PP2>D/kb10I$)L<2etI]'_.Y`=d#'PZ.tHxh*=ksu7XN>1(aN+H; path=/; expires=Mon, 08-Oct-2012 09:43:50 GMT; domain=.adnxs.com; HttpOnly ANONCHK=0; domain=c.fr.msn.com; expires=Fri, 13-Jul-2012 09:43:05 GMT; path=/; apicit=2f3c1bc3b388a8cdd80f3512246ff556; expires=Wed, 10-Jul-2013 09:43:51 GMT; path=/; domain=.apicit.net au=H4GSTRKR-5HPK-10.42.9.189; Domain=.rubiconproject.com; Expires=Wed, 08-Jul-2020 09:49:55 GMT; Path=/ AVPUID=93f6bd2725463d229992aa0fb0f74c33; Expires=Wed, 10-Jul-2013 09:43:42 GMT; Path=/ B4=iiFw0000000000000000B2itqq0000000001000000B2iz8I0000000000000000B1fH770000000000000000BeiBSe0000000001000000BeitkN0000000001000000B2iuXe0000000001000000B2i6D70000000001000000B2im+d0000000002000000B2; expires=Mon, 08-Oct-2012 05:49:54 GMT; domain=.serving-sys.com; path=/ bh=\ bk=CIOGLXV5c/saNx3a; expires=Sun, 06-Jan-2013 09:49:40 GMT; path=/; domain=.bluekai.com bkc=KJ0fJXe9W1wYyne8Nt2dOi999YzlOWR=; expires=Sun, 06-Jan-2013 09:49:39 GMT; path=/; domain=.bluekai.com bkc=KJhnWsHQtO41hneNNt2dHQRsCQxQ4f6Wv7XPsMIsCxcm8IHiRBQt7RaCYh/d5uG3wysBftsW0Q4H1wT29SObGcrxIH3z3cycqkEN/w5LCF/O+sz6pQ==; expires=Sun, 06-Jan-2013 09:49:41 GMT; path=/; domain=.bluekai.com bkc=KJpM8sJQteS5QVcng2dIM9y1eJh94roDPcTYs+deYJDwGZcXKyJ92za1vcyBEkuI9pK3ICQVOGqBDeT9/G6A/Q==; expires=Sun, 06-Jan-2013 09:49:40 GMT; path=/; domain=.bluekai.com bkdc=snv; expires=Thu, 09-Aug-2012 09:49:39 GMT; path=/; domain=.bluekai.com bk=ghIu1ufHyEKaNx3a; expires=Sun, 06-Jan-2013 09:49:41 GMT; path=/; domain=.bluekai.com bklc=4ffbfab4; expires=Thu, 12-Jul-2012 09:49:40 GMT; path=/; domain=.bluekai.com bko=; expires=Sun, 06-Jan-2013 09:49:39 GMT; path=/; domain=.bluekai.com bko=KJhnWZPQtwgg+pXM9y9ukQB0; expires=Sun, 06-Jan-2013 09:49:41 GMT; path=/; domain=.bluekai.com bkp1=; expires=Sun, 06-Jan-2013 09:49:39 GMT; path=/; domain=.bluekai.com bkst=KJhMRDQxjsOxREOJu6+vLpxh6gDy167VEExp12xNE6yt6eVtEeBnEeJ1+exlBBdbbfzd9whteHW=; expires=Sun, 06-Jan-2013 09:49:41 GMT; path=/; domain=.bluekai.com bku=lC999nwbI6IzdcAs; expires=Sun, 06-Jan-2013 09:49:39 GMT; path=/; domain=.bluekai.com bk=vKTNk1V5c/saNx3a; expires=Sun, 06-Jan-2013 09:49:39 GMT; path=/; domain=.bluekai.com bkw5=; expires=Sun, 06-Jan-2013 09:49:39 GMT; path=/; domain=.bluekai.com bkw5=KJypisaQSmnxRDoCRs9xjPQjhXe901eJkE3PQxW9BDze6y==; expires=Sun, 06-Jan-2013 09:49:41 GMT; path=/; domain=.bluekai.com bsuid=%3Eb%29wX-kFDueh%2AZM; path=/; domain=.rtbidder.net; expires=Mon, 08-Oct-2012 09:43:31 GMT c1=4FFBF92E025400F4; expires=Sun, 09-Jul-2017 09:43:10 GMT; path=/pmu/ C3=AgAAAB+LCAAAAAAABADsvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymrKoHKZVZlXWYWQMztnbz33nvvvffee++997o7nU4n99//P1xmZAFs9s5K2smeIYCqyB8/fnwfPyJ2fub/CQAA//8bGSzHAgAAAA==; domain=atemda.com; expires=Sat, 08-Sep-2012 09:43:50 GMT; path=/ CC=AT; domain=.msn.com; expires=Thu, 10-Jul-2014 09:43:04 GMT; path=/ cd=false; Domain=.rubiconproject.com; Expires=Wed, 10-Jul-2013 09:49:55 GMT; Path=/ __cfduid=d1edd36f6a7f9722c19d4b62a2d176ceb1341913774; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.css.kameleoon.com CFID=238634555; expires=Sun, 27-Sep-2037 00:00:00 GMT; path=/; domain=.rueducommerce.fr; CFID=238634555; path=/; CFID=;expires=Tue, 10-Jul-2012 08:50:39 GMT;path=/;domain=.rueducommerce.fr; CFMAGIC=238634555%3A30294847; expires=Sun, 27-Sep-2037 00:00:00 GMT; path=/; domain=.rueducommerce.fr; CFMAGIC=;expires=Tue, 10-Jul-2012 08:50:39 GMT;path=/;domain=.rueducommerce.fr; CFTOKEN=30294847; path=/; CFTOKEN=;expires=Tue, 10-Jul-2012 08:50:39 GMT;path=/;domain=.rueducommerce.fr; ck=1; Domain=.email-attitude.com; expires=Wed, 11-Jul-2012 09:50:41 GMT; httponly; Path=/ clicks=;Path=/;Domain=invitemedia.com;Expires=Thu, 01-Jan-1970 00:00:01 GMT comp=s10936=crtg%3Dtrue; expires=Wed, 08-Aug-2012 22:00:00 GMT; path=/ cookie_pooling=eyIxMjExMiI6MH0%3D; path=/; expires=Sat, 08-Sep-2012 09:43:29 GMT CR=; domain=.fnac.com; expires=Mon, 09-Jul-2012 09:44:07 GMT; path=/ CRITEO=ok; path=/; expires=Thu, 09-Aug-12 09:49:48 GMT; domain=.prisma-presse.com critg3=1; expires=Thu, 09-Aug-12 09:49:48 GMT; path=/; domain=.ftv-publicite.fr crtgmc=1;expires=Thu, 9 Aug 2012 9:49:48 GMT;domain=adtech.de;path=/ crtgmc2=1;expires=Thu, 9 Aug 2012 9:49:48 GMT;domain=adtech.de;path=/ crtgmegaban=1; expires=Thu, 09-Aug-12 09:49:48 GMT; path=/; domain=.leboncoin.fr crtgpave=1; expires=Thu, 09-Aug-12 09:49:48 GMT; path=/; domain=.leboncoin.fr csi15=3322954.js^1^1341913779^1341913779; expires=Tue, 17-Jul-2012 09:49:39 GMT; max-age=604800; path=/; domain=.rubiconproject.com; csi2=3282012.js^1^1341913409^1341913409; expires=Tue, 17-Jul-2012 09:43:29 GMT; max-age=604800; path=/; domain=.rubiconproject.com; csi2=3298098.js^1^1341913410^1341913410&3282012.js^1^1341913409^1341913409; expires=Tue, 17-Jul-2012 09:43:30 GMT; max-age=604800; path=/; domain=.rubiconproject.com; _csimf=Mj1TOjEyODY7; domain=.advideum.solution.weborama.fr; path=/ D0=@f^ku^FABf^ku^FAD>>^>>; expires=Sun, 27-Sep-2037 00:00:00 GMT; path=/; D0=@f^ku^FABfnckpHAD>>^>>; expires=Sun, 27-Sep-2037 00:00:00 GMT; path=/; dis=*1fzNBMAhgurs%2fiDR8GiE7ag%3d%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:43:06 GMT; path=/ dis=*1H4mMZRl%2fiqo1yuqceX30KAeiZodceu34kopHLAOxqygPtqix7bj0n8VYnpC4ZZuWOT%2fyfByaUR6YuGkiAVGn3pV4Ob6ndgv8D3g%2bmV%2bn7Jj%2bsJg8qgCZ%2f%2br6mcQAN4mEhmG8yEr1Q%2fFHoUkmNuBkkXU9YaBTJzVSzZ%2fsNWNH9h6iudNDfO3XOjSpTDref1jJR82AtWiXvEr4cbjW4Ya9DA%3d%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:49:48 GMT; path=/ dis=*1wDaHwy0hF8DRRAQewdU1bd1n7ts3ELxPZkYpi%2bFJw284kWJXuiWQ5JEirFjf8NQ4Evw60mviNlcfIdZLHJxXlwQ9c8mBkUPKpkWDO1VAJrGwi1wylT7bcZd4LCYFeNdq6dYC8VLzLFibYCGy6DtXR9Y195zZdgvbNGeGC8mMXE4xGSo8vRpRNExRUQS9%2fxNcR01l5YRfz46pk85k8dNDtA%3d%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:50:41 GMT; path=/ dq=1|1|0|0; Expires=Wed, 10-Jul-2013 09:49:55 GMT; Path=/ DTN=10%2f07%2f2012+11%3a44%3a07; domain=.fnac.com; expires=Sun, 09-Jul-2017 09:44:07 GMT; path=/ dyncdn=1; expires=Wed, 11-Jul-2012 09:43:32 GMT; domain=smartadserver.com; path=/ dyncdn=limit; expires=Wed, 11-Jul-2012 09:50:36 GMT; domain=smartadserver.com; path=/ e=cr;Path=/;Domain=.rfihub.com;Expires=Sat, 27-Dec-14 09:49:56 GMT ELOQUA=GUID=93271EDB2DC744749117085275C71CE5; domain=.eloqua.com; expires=Sun, 01-Dec-2030 02:30:00 GMT; path=/ ELQSTATUS=OK; domain=.eloqua.com; expires=Sun, 01-Dec-2030 02:30:00 GMT; path=/ eptic_cookie=erlangorg@hades-1326360052369809409; path=/ et0=9WEzt.Ng_QO_4I.lc2tpaxPhN.bxac5tD17LbNfUzr4nC2.0Ug0AF1WTcTz0hN3751KuxtXF_634DpnmdGPnrg7Uf3Q3MUaJkrG9GJQRZZgGVg7k890.QkT.vX.d2zM1uneeVpa7hMuMMDDpSQvEhK_jW1lBwfMhpe6flcfmRh4a8VeQbe9R.h18qGk08qt9; expires=Sun, 06 Jan 2013 09:50:35 GMT; path=/; domain=ea.rueducommerce.fr et0=DEQwyRwgEDJm_8YpRfjMNfr81T2YubR9AIbwQaws7P9ovI48erotV7sfikoW06cJq74qI9GCu6DF8mimmn6u.7JhQK27yN6ywhLuOOoa_3OxjTTclYgcS0Gct8LiYEyMFB71LsTIL6H7aX_FEHx6.XyLBipd1wvUVl3k9U_0YM8-; expires=Sun, 06 Jan 2013 09:43:42 GMT; path=/; domain=ea.rueducommerce.fr et0=EMfNwnYS.kZtdivW2dV4b.WG75bayPfxh6FIDZbemsSzePHbHah0kxWvp43XyrtaNC0.LiXGklAYTn8fdBYdZBrANG2jiIAwmpociX5B6Pjosy0ojvHxgi8QagKwBDnHqslhU8TomqXj4Qao7iEi7VDIK.Q6s3yVgS1W6M6Y3ab5BJDjS.qAdZqCpflwSHkNV1JvKDz7tQ_J1MLYf4zHhvUj; expires=Sun, 06 Jan 2013 09:50:41 GMT; path=/; domain=ea.rueducommerce.fr et0=; path=/; domain=.rueducommerce.fr; expires=Thu, 01-Jan-1970 00:00:01 GMT et0=SmMvxkqDL6S1a502afB.opccmYKS_nbU2rbi_y6ktNg.0pSqYsAkT_yMMGa63iZ0t67U4nklYU3ANs0wgjXKxeaK2fjtGFw3rO0pY4s0bMgUjHDlJhDps82vZr60YCRChOvL4T0g02ZmP3fdz9Mx79ZLH1TCsbgl6d6kg0T3hxickJ1QewI4YRcb0qnYYRxxcw--; expires=Sun, 06 Jan 2013 09:50:36 GMT; path=/; domain=ea.rueducommerce.fr et0=w8QJGwZp6DPssZVf3FnOX1eo5bnF_ACWUWg6wyGjPBlVrF.hgYSDwc0eeI4zPDzR4PbMzKSqAiWTyrq90TG6OwblkvD.3fb67DjjGXYnwu1k6EgglrqZQ3IaL6P_VqUi6NS07qEvPIJ8z3DuMatsKQmNRz6L9lk-; expires=Sun, 06 Jan 2013 09:43:39 GMT; path=/; domain=ea.rueducommerce.fr et=1; expires=Sun, 06 Jan 2013 09:43:32 GMT; path=/; domain=ea.rueducommerce.fr et=; path=/; domain=.rueducommerce.fr; expires=Thu, 01-Jan-1970 00:00:01 GMT etuid=HsfIsvrQ2KD7kdXuQNLNpg--; expires=Sun, 06 Jan 2013 09:43:32 GMT; path=/; domain=ea.rueducommerce.fr etuid=; path=/; domain=.rueducommerce.fr; expires=Thu, 01-Jan-1970 00:00:01 GMT evt=*1%2bdRRFIG8C4z%2bBLk7y%2fCqZg%3d%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:43:05 GMT; path=/ evt=*14fEfBc6rpooYSJeBK59zyw%3d%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:43:39 GMT; path=/ evt=*1i598YGHsxaxo%2boAGyfZz9fzNJ5YSI4XoXExAymxdPvc%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:44:10 GMT; path=/ evt=*1YD4naks8XoliPm8l1HOgnZ%2fMVR%2brxElZb0ZH3AqPvjy00aGSWsjEV7N2yMxEGv6mFrO%2b5Qt4YBnZlADavsB%2bDw%3d%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:50:41 GMT; path=/ evt=*1ZEXmMy5okGbnLEYwqTASQA%3d%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:43:42 GMT; path=/ eZSESSID=00673aaac6d25622b6afb23178eb83ba; path=/ _fcap_CAM3=AEYAQwBBAFAAAAAA; Domain=outbrain.com; Expires=Wed, 11-Jul-2012 09:49:55 GMT; Path=/ FMBasketProductsCount=0; domain=.fnac.com; expires=Sun, 09-Jul-2017 22:00:00 GMT; path=/ frequency=;Path=/;Domain=invitemedia.com;Expires=Thu, 01-Jan-1970 00:00:01 GMT _FS=NU=1; domain=.bing.com; path=/ IAASRC=%7C92%3A1344505788%7C22%3A1347097788%7C10%3A1347097788%7C; expires=Wed, 10-Jul-2013 09:49:48 GMT; path=/; domain=.a2dfp.net iab=status=Optin&token=45EE30E3557C4B778EA7A6161BDC1175; expires=Wed, 08-Aug-2012 22:00:00 GMT; domain=.smartadserver.com; path=/ i=c01d6d45-9f7a-40d7-8709-043e1a93c4e3; expires=Thu, 10-Jul-2014 09:43:50 GMT; path=/; domain=.openx.net id=4612108434589598973; path=/; domain=.mookie1.com; expires=Sun, 04-Aug-2013 09:49:44 GMT ID=AAAAAQAU_8T.etNQfIqRI6xAhfZNbGy0qMABAKSostXIaUF3q2S2nS_LieMAAAE4cEtROgAAAAAAAAAA; Domain=.amgdgt.com; Expires=Fri, 08-Jul-2022 09:49:40 GMT; Path=/ id=c3c24b5d-be8b-4576-b27b-c00c21db9f00; Domain=.yieldlab.net; Expires=Wed, 10-Jul-2013 09:43:50 GMT; Path=/ ihlb=\ impressions=;Path=/;Domain=invitemedia.com;Expires=Thu, 01-Jan-1970 00:00:01 GMT infos=deleted; expires=Mon, 11-Jul-2011 09:50:46 GMT; path=/; domain=.yakaz.com io_frequency=;Path=/;Domain=invitemedia.com;Expires=Thu, 01-Jan-1970 00:00:01 GMT _i_rc=1; Domain=chango.com; expires=Tue, 17 Jul 2012 09:49:40 GMT; Path=/ j=c638666722680058483;Path=/;Domain=.rfihub.com JSESSIONID=04b86202a3d42f4b3cea144e6351; Path=/ K=@@GF_zDCB>?Vu@?; expires=Sun, 27-Sep-2037 00:00:00 GMT; path=/; KRTBCOOKIE_257=4743-uid:2c03d2f2-cc75-449e-9d9f-2a0002ae6603; domain=pubmatic.com; expires=Mon, 08-Oct-2012 09:49:46 GMT; path=/ KRTBCOOKIE_277=5114-4918409058730637084; domain=pubmatic.com; expires=Fri, 10-Jul-2015 09:43:50 GMT; path=/ lbdis=; domain=.criteo.com; expires=Mon, 09-Jul-2012 09:43:05 GMT; path=/ LIG_Y=\ livep=0; domain=.weborama.fr; path=/; expires=Tue, 03-Jul-2012 00:04:51 GMT lm=\ lm_userid=3VkGpAOQg4I; Domain=.lucidmedia.com; Expires=Wed, 10-Jul-2013 09:49:41 GMT; Path=/ LO=AAAAAQAU1z3aJooen5CpY2_6wuritdK0tr0CAGZyYTtqOzI1MDA3NTtwYXJpczs3NTAwMTtuZW90ZWxlY29tcyBnbG9iYWwgYmFja2JvbmU7YnJvYWRiYW5kOzQ2LjI1NS4xNzYuMjsyOTE2NjAyMzQyO3Q-; Domain=.amgdgt.com; Expires=Thu, 09-Aug-2012 09:49:40 GMT; Path=/ lowcrtgmega=1; expires=Thu, 09-Aug-12 09:49:48 GMT; path=/; domain=.leboncoin.fr LSA=; domain=.fnac.com; expires=Mon, 09-Jul-2012 09:44:07 GMT; path=/ LSASubsite=; domain=.fnac.com; expires=Mon, 09-Jul-2012 09:44:07 GMT; path=/ LSI=-1=AAB#MDALA#APW8k|B|MDALA|AAaTA; domain=.fnac.com; expires=Sun, 09-Jul-2017 09:44:07 GMT; path=/ LSI=-53=AAB#MDALF#APiLM|B|MDALF|AAAAA&-1=AAB#MDALA#APW8k|B|MDALA|AAaTA; domain=.fnac.com; expires=Sun, 09-Jul-2017 09:49:45 GMT; path=/ _lvd2=\ MC1=V=3&GUID=646349bb85a946ef94e11b6d6318d93d; domain=.msn.com; expires=Mon, 04-Oct-2021 12:00:00 GMT; path=/ mdata=1|4612108434589598973|1341913784; path=/; domain=.mookie1.com; expires=Sun, 04-Aug-2013 09:49:44 GMT meld_sess=8c2a50cd-fde4-4570-bbf0-53ad30434207;expires=Wed, 10 Jul 2013 09:43:50 GMT;path=/;domain=tag.admeld.com; mh=MSFT; domain=.msn.com; expires=Thu, 10-Jul-2014 09:43:04 GMT; path=/ mt_mop=9:1341913781|4:1341913781|10010:1341913781; domain=.mathtag.com; path=/; expires=Fri, 10 Jul 2015 09:49:41 GMT MUID=27085269B51A65772C2F51F0B11A6510&TUID=1; domain=.msn.fr; expires=Thu, 10-Jul-2014 09:43:10 GMT; path=/; Nav1=; domain=.fnac.com; expires=Mon, 09-Jul-2012 09:44:07 GMT; path=/ NBART=0; domain=.fnac.com; expires=Sun, 09-Jul-2017 22:00:00 GMT; path=/ NSC_fd1efm_qppm_iuuq=ffffffff09099ec145525d5f4f58455e445a4a423660;path=/;httponly nus_2307=1.00; expires=Tue, 10-Jul-2012 21:43:29 GMT; max-age=43200; path=/; domain=.rubiconproject.com o=1-pZDXDpAXl833;Path=/;Domain=.rfihub.com;Expires=Sat, 27-Dec-14 09:49:56 GMT OACBLOCK=; domain=.criteo.com; expires=Fri, 10-Aug-2012 09:43:05 GMT; path=/ OACCAP=; domain=.criteo.com; expires=Fri, 10-Aug-2012 09:43:05 GMT; path=/ OAID=6177312769cd2d055aff5e5739fc1afa; expires=Wed, 10-Jul-2013 09:43:32 GMT; path=/ OASCCAP=; domain=.criteo.com; path=/ OAX=Lv+wAk/7+T8ADf8T; expires=Thu, 31-Dec-2020 23:59:59 GMT; path=/; domain=.uniprix.nouvelobs.com OAX=Lv+wAk/7+TEADosA; expires=Thu, 10-Jul-14 09:43:13 GMT; path=/; domain=.lemonde.fr OAX=Lv+wAk/7+WoAAZkg; path=/; expires=Thu, 10-Jul-14 09:44:10 GMT; domain=.247realmedia.com obuid=3fed2de9-f001-4d13-b7de-28453cbbe086; Domain=outbrain.com; Expires=Fri, 05-Jul-2013 09:49:55 GMT; Path=/ OrderInSession=0; domain=.fnac.com; path=/ ORGN=FnacAff; domain=.fnac.com; expires=Sun, 09-Jul-2017 09:43:47 GMT; path=/ ORIGDT=10%2f07%2f2012+11%3a43%3a47; domain=.fnac.com; expires=Sun, 09-Jul-2017 09:43:47 GMT; path=/ p=1341913409; version=1; path=/; domain=.openx.net; max-age=63072000; p=1-pZDXDpAXl833;Path=/;Domain=.rfihub.com pbw=%24b%3D16999%3B%24o%3D99999%3B%24sh%3D1024%3B%24sw%3D1600; expires=Mon, 30-Jun-2014 09:43:32 GMT; domain=smartadserver.com; path=/ pbwmaj6=y; expires=Thu, 12-Jul-2012 09:43:32 GMT; domain=smartadserver.com; path=/ phpAds_partner3=eAFTNDKoMTQ2MbQ0NDa3sLAGsU1MDUyBbABOzgXR; expires=Thu, 09-Aug-2012 09:49:48 GMT; path=/a; domain=.advertstream.com PID=20; domain=.fnac.com; expires=Tue, 10-Jul-2012 19:43:49 GMT; path=/ pid=5100585566948287292; expires=Mon, 30-Jun-2014 09:43:32 GMT; domain=smartadserver.com; path=/ PID=; domain=.fnac.com; expires=Sat, 30-Jun-2012 09:43:53 GMT; path=/ pluto2=296722456235; domain=.fastclick.net; path=/; expires=Thu, 10-Jul-2014 09:49:49 GMT pma=S7QysKquBQA%3D; expires=Tue, 31-Dec-2013 22:59:59 GMT; path=/ pmc2=MzBAAoYGgwkAAA%3D%3D; expires=Tue, 31-Dec-2013 22:59:59 GMT; path=/ _pooling=1; path=/ PUBRETARGET=2615_1436521430.2452_1349689786; domain=pubmatic.com; expires=Fri, 10-Jul-2015 09:43:50 GMT; path=/ px=0b83a084-dd0b-4bfe-9e2e-ab3706fc9955.1341913410; version=1; path=/; domain=.openx.net; max-age=31536000; r=1341913796342;Path=/;Domain=.rfihub.com;Expires=Sat, 27-Dec-14 09:49:56 GMT _rcc2=\ rdk15=0; expires=Tue, 10-Jul-2012 10:43:29 GMT; max-age=10; path=/; domain=.rubiconproject.com recs-666855272430de0575cf6b64000d861d=\ RMFL=011SoWyeU10105H|U101081; expires=Thu, 31-Dec-2020 23:59:59 GMT; path=/; domain=.uniprix.nouvelobs.com rpb=8981%3D1%269073%3D1%267751%3D1%267727%3D1%264222%3D1%267249%3D1%2611203%3D1%267259%3D1%2610573%3D1%264554%3D1%2613490%3D1%265328%3D1%265852%3D1%266434%3D1; expires=Thu, 09-Aug-2012 09:50:41 GMT; path=/; domain=.rubiconproject.com rpb=8981%3D1; expires=Thu, 09-Aug-2012 09:43:30 GMT; path=/; domain=.rubiconproject.com rpx=8981%3D22105%2C0%2C1%2C%2C%269073%3D22105%2C0%2C1%2C%2C%267751%3D22105%2C0%2C1%2C%2C%267727%3D22105%2C0%2C1%2C%2C%264222%3D22105%2C0%2C1%2C%2C%267249%3D22105%2C0%2C1%2C%2C%2611203%3D22105%2C0%2C1%2C%2C%267259%3D22105%2C0%2C1%2C%2C%266434%3D22105%2C0%2C1%2C%2C%2610573%3D22105%2C0%2C1%2C%2C%264554%3D22105%2C0%2C1%2C%2C%2613490%3D22105%2C0%2C1%2C%2C%265328%3D22105%2C0%2C1%2C%2C%265852%3D22105%2C0%2C1%2C%2C; expires=Thu, 09-Aug-2012 09:49:56 GMT; path=/; domain=.pixel.rubiconproject.com rsid=CMuNRCnwr4RJFvOudUoCwqBpLKWcxgZprODTJBmN+jd4CMChZh/4S5wOdeVRmsAx2thOzx8Vu3HJcuIkd4IzUZBM4a4xIyWaasWi6suxAaxdPo9e; path=/; domain=.rubiconproject.com; RT1=AAAAAA2; domain=atemda.com; expires=Sat, 08-Sep-2012 09:43:50 GMT; path=/ ruid=592cc2264ffbf9412effb00221957a^1^1341913409^788508674; expires=Mon, 08-Oct-2012 09:43:29 GMT; max-age=7776000; path=/; domain=.rubiconproject.com; s1=4FFBF92E025400F3; expires=Sun, 09-Jul-2017 09:43:10 GMT; path=/pmu/pmu-fr/ s3=1341913796342;Path=/;Domain=.rfihub.com;Expires=Sat, 27-Dec-14 09:49:56 GMT s=7cd87936-6b7f-4ccb-972d-d03dc8131373; version=1; path=/; domain=.openx.net; sasd=%24a%3D0t%3B%24cn%3D0%5F0%3B%24isp%3D0%3B%24qc%3D1310896006%3B%24ql%3Dunknown%3B%24qpc%3D75001%3B%24qpp%3D0%3B%24qt%3D184%5F1903%5F42652t; path=/ sasd=%24qt%3d184_1903_42652t%3b%24qc%3d1310896006%3b%24ql%3dunknown%3b%24qpc%3d75001%3b%24qpp%3d0; domain=.aufeminin.com; expires=Wed, 11-Jul-2012 09:49:34 GMT; path=/ sasd2=q=%24qt%3d184_1903_42652t%3b%24qc%3d1310896006%3b%24ql%3dunknown%3b%24qpc%3d75001%3b%24qpp%3d0&c=&a=-362289870&l=&lo=<=634775177741863673; domain=.aufeminin.com; expires=Wed, 11-Jul-2012 09:49:34 GMT; path=/ segments=;Path=/;Domain=invitemedia.com;Expires=Thu, 01-Jan-1970 00:00:01 GMT SERVERID=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/ ses15=14319^1&16416^1; expires=Wed, 11-Jul-2012 02:59:59 GMT; max-age=79820; path=/; domain=.rubiconproject.com sess=1; path=/; expires=Wed, 11-Jul-2012 09:43:50 GMT; domain=.adnxs.com; HttpOnly SESS708c3152436f834213664fa2546e7125=6v9ds52ov3o6optsgovtc969i1; expires=Thu, 02 Aug 2012 12:33:49 GMT; path=/; domain=.springsource.com session-id=277-5453710-9941953; path=/; domain=.amazon.fr; expires=Mon, 31-Dec-2035 23:00:01 GMT session-token=7D0Zg+vD5hA+HmZhHNW0JdZh7EVDw7g5rfIBzLxWNHwuOOcI4pw7V8R37ePBlfF/XSCdbvX/92dXFLOg1GQqYW0Nq+rpHH91uXHByaGzSS5RpQ/L9dZhtKKGXWyJxmTHDoNYw8nNUC4sMO3jyVT4ll3BzGoGYF1ZYZPiZXD0m/mSc1oJmMkLlCHX6rw0fwbISjKFANUrWiu8i/3GSQSuoFb6peqoXp6OirSVgGlmDeC0D5GZCAHJEFWnt15B7QSPGC09oAa8y4c=; path=/; domain=.amazon.fr; expires=Mon, 05-Jul-2032 09:45:02 GMT SID=82d94861-89d7-a8cf-34e6-826ccbecdaa2; domain=.fnac.com; expires=Sun, 06-Jan-2013 10:43:47 GMT; path=/ SRCHD=D=2379463&MS=2379463&AF=NOFORM; expires=Thu, 10-Jul-2014 09:43:05 GMT; domain=.bing.com; path=/ _SS=SID=8D241D446707420E97BF3F711A93556D; domain=.bing.com; path=/ s_vi=[CS]v1|27FDFCAB05011FC6-600001126012CC17[CE]; Expires=Sun, 9 Jul 2017 09:43:50 GMT; Domain=.fnac.com; Path=/ _t=9176626e-ca74-11e1-9043-00259035d4c0; Domain=chango.com; expires=Fri, 08 Jul 2022 09:49:40 GMT; Path=/ tc=1; Expires=Wed, 10-Jul-2013 09:43:31 GMT; Path=/ TDCPM=CAESFgoHcnViaWNvbhILCPTwn5S0qNYvEAUYAyABKAIyCwjYx7vAyqjWLxAF; domain=.adsrvr.org; expires=Wed, 10-Jul-2013 09:43:30 GMT; path=/ TDCPM=CAEYAygCMgsI2Me7wMqo1i8QBQ==; domain=.adsrvr.org; expires=Wed, 10-Jul-2013 09:43:29 GMT; path=/ TDID=eed09d9b-68a5-46c8-85e1-231e745057e7; domain=.adsrvr.org; expires=Wed, 10-Jul-2013 09:43:29 GMT; path=/ TestIfCookieP=ok; domain=.aufeminin.com; expires=Tue, 09-Jul-2013 22:00:00 GMT; path=/ tpv1=; domain=atemda.com; expires=Mon, 09-Jul-2012 09:43:50 GMT; path=/ trgu=2682edfe-500d-4496-87b9-a7253582a8f9; domain=.triggit.com; path=/; expires=Thu, 10-Jul-2014 00:00:00 GMT ts=1341913410; domain=.mathtag.com; path=/; expires=Wed, 10-Jul-2013 09:43:30 GMT tst=*1UIjtkHbGKaVQiMH9h2VVmw%3d%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:43:05 GMT; path=/ tuuid=40430961-c3df-4dce-baf2-cf7776d6f3ac; path=/; expires=Thu, 10-Jul-2014 09:49:56 GMT; domain=.wtp101.com u2=19c940e9-829f-4c87-bdf8-316d75bf0c483Ou09g; expires=Mon, 08-Oct-2012 05:43:14 GMT; domain=.serving-sys.com; path=/ U=63B9CAB9A0C18D5102C9D3C76F1B1756; expires=Sun, 27-Sep-2037 00:00:00 GMT; path=/; UA=AAAAAQAUhbyg89ABz3rKqGPKvW5HUsOWJMYEA3gBY2BgYGRg3nWegW3RDgbG_QcYGLPvMUAAJ1DKosA70ArKZ_D_XdAAYgNFvTY9gOpjVAhiXcgIUQIAUiUOpg--; Domain=.amgdgt.com; Expires=Thu, 09-Aug-2012 09:49:40 GMT; Path=/ ubid-acbfr=275-1998587-8474020; Domain=.amazon.fr; Expires=Mon, 05-Jul-2032 09:49:40 GMT; Path=/ udc=*1Z3JmtlfKLQPI8Kj%2bhFX5nbonq798hnGSd7H9b5cEUG6zS%2fnVwErgCJQjfXuQo4zX; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:44:10 GMT; path=/ udi=*10tunx0bK7pW5o1%2bQ2Mz30Q%3d%3d; domain=.criteo.com; expires=Wed, 11-Jul-2012 09:43:05 GMT; path=/ ug=WvuqLohn_jnCwA; Domain=.adviva.net; Expires=Sun, 09-Jul-2017 09:49:54 GMT; Path=/ uic=*14%2b2NUPum7ePb5JJjkZeYz%2fcxXhpAcWavNWs2aE7R3bsr%2fRv3X7veBsfa8L0L%2fQ99dZ74%2bJ53tMWD2TBx4029zmKw7ul%2fhczHkRVnOuSknjU%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:49:48 GMT; path=/ uic=*14sPCqQDxBeVOntYHr6vKp9wU%2bHRWvrDEPYh7O0Re%2f31%2bmPpOxrXXj0JkdgNWdm1Y; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:43:42 GMT; path=/ uic=*1asNezGgqHy3CH9sBLD5U9OJ2jf%2bquLuqlhFB%2b6vS5QgtUNIYzRLXadpJDpxwVuGW; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:43:39 GMT; path=/ uic=*1RagJ%2bQRxyvWRLNqdSaP7xYW95LenV4dLRNRMTSGtfQpxwMjYgolJpbg5SouNxEk57bkuIiku50jjsj1E4DHoYKvKLzZJhglg16bRlyyVLEsPbCk9bA7h87n3eVupyO1aqjqFlWRzSrq%2bmL2744yzd7afdfCQ3iA700TOZrOdILFZHncOXKbggl3d2jtr%2fmWE; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:50:41 GMT; path=/ uic=*1zYQZfkxvNs7NzKaoBbkzzQ%3d%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:43:05 GMT; path=/ UID=07185ED49-1A26-FE6A-6A98-DB34B9DCC784; domain=.fnac.com; expires=Sun, 09-Jul-2017 09:43:47 GMT; path=/ uid=2c03d2f2-cc75-449e-9d9f-2a0002ae6603; domain=.criteo.com; expires=Wed, 10-Jul-2013 09:43:05 GMT; path=/ uid=VAAeAjUAAg5STBECAIADkQ==; expires=Sun, 09-Jul-17 09:49:56 GMT; domain=relestar.com; path=/ UM1=AAEAAB-LCAAAAAAABADsvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymrKoHKZVZlXWYWQMztnbz33nvvvffee--997o7nU4n99__P1xmZAFs9s5K2smeIYCqyB8_fnwfPyKSX_gb_Ma_xUfJb7n_cPdgf-fhzv2DB_d2Pr33YOdg_7f4DX-Df-iP-Ht_xT_81_wbd3-zX_fX-P_p8_8EAAD__6xGKhAAAQAA0; domain=atemda.com; expires=Sat, 08-Sep-2012 09:43:50 GMT; path=/ UMAP=MTAwNzoxMzQxOTEzNzgy; domain=advertising.com; expires=Thu, 10-Jul-2014 09:49:42 GMT; path=/ uu=406371341913430612; Domain=.adscale.de; Expires=Mon, 08-Jul-2013 02:10:30 GMT; Path=/ uuid2=1895376179915936457; path=/; expires=Mon, 08-Oct-2012 09:43:50 GMT; domain=.adnxs.com; HttpOnly uuid=4ffbf942-864c-a661-7ac0-39f6ab1a9717; domain=.mathtag.com; path=/; expires=Wed, 10-Jul-2013 09:43:30 GMT v=1341913796342;Path=/;Domain=.rfihub.com;Expires=Sat, 27-Dec-14 09:49:56 GMT V=3; expires=Sun, 27-Sep-2037 00:00:00 GMT; path=/; vi=3ec17386424d4436b71bb76c4c9820a3; domain=atemda.com; expires=Sat, 08-Sep-2012 09:43:50 GMT; path=/ vs=13992=5009023; domain=smartadserver.com; path=/ vs=1=5009029; domain=.aufeminin.com; path=/ vuid=906400c82ea25016b2569e01703b3f9a4ffbf9553d6dd; expires=Thu, 10-Jul-2014 09:43:49 GMT; path=/ zob=*19rF3iWM0WAJdLU0SC1aJ6w%3d%3d; domain=.criteo.com; expires=Thu, 10-Jan-2013 10:43:05 GMT; path=/ yaws-2.0.2/test/eunit/gconf.erl0000664000175000017500000000637012605311413013326 00000000000000-module(gconf). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). -include("yaws.hrl"). -include("tftest.hrl"). setup_default_gconf_test() -> Dir = yaws_dir(), EbinDir = Dir++"/examples/ebin", IncDir = Dir++"/examples/include", GC = yaws_config:make_default_gconf(false, "test"), GC = yaws:create_gconf([], "test"), Flags = case yaws_sendfile:have_sendfile() of true -> 1124; false -> 100 end, true = is_same_path(Dir, get_gconf_attr(yaws_dir, GC)), true = is_same_path(EbinDir, get_gconf_attr(ebin_dir, GC)), true = is_same_path(IncDir, get_gconf_attr(include_dir, GC)), {trace, false} = get_gconf_attr(trace, GC), {flags, Flags} = get_gconf_attr(flags, GC), {id, "test"} = get_gconf_attr(id, GC), ok. set_gc_flags_test() -> GC = yaws:create_gconf([], "test"), {tty_trace, true} = check_gc_flags(tty_trace, ?GC_TTY_TRACE, GC), {debug, true} = check_gc_flags(debug, ?GC_DEBUG, GC), {copy_errlog, true} = check_gc_flags(copy_errlog, ?GC_COPY_ERRLOG, GC), {backwards_compat_parse, true} = check_gc_flags(backwards_compat_parse, ?GC_BACKWARDS_COMPAT_PARSE, GC), {fail_on_bind_err, true} = check_gc_flags(fail_on_bind_err, ?GC_FAIL_ON_BIND_ERR, GC), {log_resolve_hostname, true} = check_gc_flags(log_resolve_hostname, ?GC_LOG_RESOLVE_HOSTNAME, GC), {pick_first_virthost_on_nomatch, true} = check_gc_flags(pick_first_virthost_on_nomatch, ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH, GC), {use_old_ssl, true} = check_gc_flags(use_old_ssl, ?GC_USE_OLD_SSL, GC), ok. setup_mime_types_info_test() -> GC0 = yaws:create_gconf([], "test"), undefined = yaws:gconf_mime_types_info(GC0), GC1 = yaws:create_gconf([{mime_types_info, []}], "test"), MI1 = yaws:new_mime_types_info(), MI1 = yaws:gconf_mime_types_info(GC1), MI2 = yaws:mime_types_info_mime_types_file(MI1, "/etc/mime.types"), GC2 = yaws:create_gconf([{mime_types_info, MI2}], "test"), "/etc/mime.types" = yaws:mime_types_info_mime_types_file (yaws:gconf_mime_types_info(GC2) ), ok. %% ======================================================================= get_gconf_attr(Name, GConf) -> Fun = list_to_atom("gconf_" ++ atom_to_list(Name)), {Name, yaws:Fun(GConf)}. check_gc_flags(Flag, Id, GConf0) -> Flags0 = yaws:gconf_flags(GConf0), Val0 = (Flags0 band Id) /= 0, GConf1 = yaws:create_gconf([{flags, [{Flag, not Val0}]}], "test"), Flags1 = yaws:gconf_flags(GConf1), Flags2 = yaws:flag(Flags1, Id, Val0), {Flag, (not Val0 == ((Flags1 band Id) /= 0) andalso Flags2 == Flags0)}. is_same_path(Dir1, {_, Dir2}) -> (real_dir_path(Dir1) == real_dir_path(Dir2)). yaws_dir() -> filename:dirname( %% yaws_dir/ filename:dirname( %% yaws_dir/test/ filename:dirname( %% yaws_dir/test/eunit filename:absname(code:which(?MODULE)) ) ) ). real_dir_path(Path) -> {ok, CurCwd} = file:get_cwd(), ok = file:set_cwd(Path), {ok, RealPath} = file:get_cwd(), ok = file:set_cwd(CurCwd), filename:absname(RealPath). yaws-2.0.2/test/eunit/cookies.dump0000664000175000017500000002577612605311413014064 000000000000003vvc=1; 3_idz=4A%2FVxQ%2B0m1AlCavMdUmzFb9RGt1qWYceCgzWgJeT0QG5Ce8crypiNLNEElsYFHwBEuKEhoFZwBXjaXf9lKQ4k912Cu%2Bp6nJ9WPNVRlkFXNDuQVeBnpkkWQinDKUjpFNT41%2F9OcqmarsuZBWUVP6S699FeCW7; vuid=906400c82ea25016b2569e01703b3f9a4ffbf9553d6dd; 3_idzp=%7B%22lastseen%22%3A0%2C%22site_id%22%3A3%2C%22chatcount%22%3A0%2C%22nbrVisite%22%3A0%2C%22ip%22%3A%2246.255.176.2%22%2C%22country%22%3Anull%2C%22country_name%22%3A%22%22%2C%22city%22%3A%22%22%2C%22lat%22%3Anull%2C%22long%22%3Anull%2C%22lang%22%3A%22fr%22%2C%22visitorname%22%3A%22+%22%2C%22extID%22%3Anull%2C%22pageview%22%3A4%2C%22connectionTime%22%3A1341913429%2C%22navTime%22%3A20000%2C%22actualURI%22%3A%22http%3A%5C%2F%5C%2Flivre.fnac.com%5C%2Fa4026148%5C%2FLe-trone-de-fer-Game-of-thrones-T13-Le-bucher-d-un-roi-George-R-R-Martin%22%2C%22origin_site%22%3A%22%22%2C%22origin%22%3A%22direct%22%2C%22refengine%22%3A%22%22%2C%22refkeyword%22%3A%22%22%2C%22timeElapsed%22%3A0.33%7D; 3_idzlast=1341913449 68vvc=1; 68_idz=Rp8OauLnfFEYqsY0FcfvxfMU3x8jstZQfIet8PDzo3xkP1reo9GH3wWadbRJGgcwYR%2BbAYJbM1SB2iue8UiNIPfVnjPOAndFl999m7fcHpYdopNLNPUlq64IOEy%2BTX%2Bts%2FdVWR0wp2rtnWQDNVejKQetQHnN; vuid=da6acda6b16e635d10b7ab70759a5faa4ffbf94404b7c; 68_idzp=%7B%22lastseen%22%3A0%2C%22site_id%22%3A68%2C%22chatcount%22%3A0%2C%22nbrVisite%22%3A0%2C%22ip%22%3A%2246.255.176.2%22%2C%22country%22%3Anull%2C%22country_name%22%3A%22%22%2C%22city%22%3A%22%22%2C%22lat%22%3Anull%2C%22long%22%3Anull%2C%22lang%22%3A%22fr%22%2C%22visitorname%22%3A%22+%22%2C%22extID%22%3Anull%2C%22pageview%22%3A3%2C%22connectionTime%22%3A1341913412%2C%22navTime%22%3A9000%2C%22actualURI%22%3A%22http%3A%5C%2F%5C%2Fwww.rueducommerce.fr%5C%2FTelephonie%5C%2F478-Smartphone%5C%2F%22%2C%22origin_site%22%3A%22%22%2C%22origin%22%3A%22direct%22%2C%22refengine%22%3A%22%22%2C%22refkeyword%22%3A%22%22%2C%22timeElapsed%22%3A0.15%7D; 68_idzlast=1341913421 AA002=1341913385-22335145; MUID=29EB989476F9660115E39B0D75F966F8 AFFICHE_W=aUy-YKwCUpzp80; _adpc=CrbTHaad; _adpp=CrbTHpYTaa; _adpe=CrcgDWa; _advcrea=bbX|bQ7.bRR|a:cb; wousq=_1341965571 afpperso=nav2012=oldnav&tcp=ok34; afperso=geo=184%2Dfr&nn=1&p%5Fpe=4&tcs=ok34&DomUser=%2Ffr bh=\ C4=; D1=; A3=BBKVd1h.0dqg00001BaUid1h.0aok00001APFTd1oO09TQ00000Bmhrd12d03Dp00000Bim0d1h.0erB00001Beysd1h.06kC00001B02ad1h.0dqe00002vVSid5wn0dqj00000; B4=itqq0000000001000000B2iiFw0000000000000000B2iz8I0000000000000000B1fH770000000000000000BeitkN0000000001000000B2iuXe0000000001000000B2im+d0000000002000000B2i6D70000000001000000B2; u2=19c940e9-829f-4c87-bdf8-316d75bf0c483Ou09g ck=1 comp=s10936=crtg%3Dtrue CRITEO=ok; NSC_fd1efm_qppm_iuuq=ffffffff09099ec145525d5f4f58455e445a4a423660 critg3=1 crtgmegaban=1; lowcrtgmega=1; crtgpave=1; lowcrtgpave=1 datr=0cDhT0YwJHnjP-9eYOm69EUN eptic_cookie=erlangorg@hades-1326360052369809409; __utma=113998419.705123879.1341910693.1341910693.1341910693.1; __utmc=113998419; __utmz=113998419.1341910693.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) e=T@whucCoAMIAACU9KloAAAJO __gads=ID=21a9c3493f59687e:T=1341913408:S=ALNI_MafqLep2U9d_eVnuZkPO5RZukWBtA; has_js=1; __utma=249856005.1255122414.1341913408.1341913408.1341913408.1; __utmb=249856005.2.10.1341913408; __utmc=249856005; __utmz=249856005.1341913408.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) guest_id=v1%3A134009689441495568; __utma=43838368.1913894811.1340096895.1340096895.1340291004.2; __utmz=43838368.1340096895.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) has_js=1; __utma=249856005.1255122414.1341913408.1341913408.1341913408.1; __utmb=249856005.1.10.1341913408; __utmc=249856005; __utmz=249856005.1341913408.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __gads=ID=21a9c3493f59687e:T=1341913408:S=ALNI_MafqLep2U9d_eVnuZkPO5RZukWBtA IAASRC=%7C92%3A1344505788%7C icu=ChIIhN8IEAYYASABKAEw1cOw_wQKEgj-kwcQChgBIAEoATDVw7D_BBDVw7D_BBgA; anj=Kfu=8fG5+^Cxrx)0s]#%2L_'x%SEV/hnK]14FV*PP2>D/kb10I$)L<2etI]'_2pvH'*a'xv:V@/d!5$(9KzOiAmx@5sh78I)HHN/; uuid2=1895376179915936457; sess=1 id=cd23d784600004d||t=1340099329|et=730|cs=002213fd48cdffc0c5eb7d533f idrxvr=82475017-B4B8-47BE-9731-24DCF6194D9E JEB2=4FEC1D2372660E44114E3BEAF010C3B3 KRTBCOOKIE_277=5114-4918409058730637084; KRTBCOOKIE_257=4743-uid:2c03d2f2-cc75-449e-9d9f-2a0002ae6603; PUBRETARGET=2615_1436521430.2452_1349689786 lowcrtgmega=1; crtgpave=1; lowcrtgpave=1; crtgmegaban=1 meld_sess=8c2a50cd-fde4-4570-bbf0-53ad30434207 NBART=0; FMBasketProductsCount=0; s_ev14=%5B%5B%27FnacAff%27%2C%271341913430091%27%5D%5D; tc_sdauid=1; tc_cj_v2=%5Ecl_%5Dny%5B%5D%5D_mmZZZZZZKMNKSKMNMJKJOZZZ%5Dfc%5De; s_vi=[CS]v1|27FDFCAB05011FC6-600001126012CC17[CE]; __sonar=4918409058730637084; s_cpc=0; LSI=-1=AAB#MDALA#APW8k|B|MDALA|AAaTA; ACT=1; DTN=10%2f07%2f2012+11%3a44%3a07; PID=30; ORGN=FnacAff; OrderInSession=0; ORIGDT=10%2f07%2f2012+11%3a44%3a07; UID=07185ED49-1A26-FE6A-6A98-DB34B9DCC784; SID=82d94861-89d7-a8cf-34e6-826ccbecdaa2; s_cc=true; __utma=147568040.1156537769.1341913430.1341913430.1341913430.1; __utmb=147568040.4.10.1341913430; __utmc=147568040; __utmz=147568040.1341913430.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); campaign=FnacAff; s_sq=fnaccomprod%3D%2526pid%253DFA%25253ALIV%25253AFiche%252520Article%2526pidt%253D1%2526oid%253Dhttp%25253A//livre.fnac.com/a4026148/Le-trone-de-fer-Game-of-thrones-T13-Le-bucher-d-un-roi-George-R-R-Mar%2526ot%253DA; Player=0; PlayerPlaying=0 OACBLOCK=; OACCAP=; OASCCAP=; uid=2c03d2f2-cc75-449e-9d9f-2a0002ae6603; tst=*1UIjtkHbGKaVQiMH9h2VVmw%3d%3d; zob=*19rF3iWM0WAJdLU0SC1aJ6w%3d%3d; dis=*1H4mMZRl%2fiqo1yuqceX30KAeiZodceu34kopHLAOxqygPtqix7bj0n8VYnpC4ZZuWOT%2fyfByaUR6YuGkiAVGn3pV4Ob6ndgv8D3g%2bmV%2bn7Jj%2bsJg8qgCZ%2f%2br6mcQAN4mEhmG8yEr1Q%2fFHoUkmNuBkkXU9YaBTJzVSzZ%2fsNWNH9h6iudNDfO3XOjSpTDref1jJR82AtWiXvEr4cbjW4Ya9DA%3d%3d; uic=*1RagJ%2bQRxyvWRLNqdSaP7xYW95LenV4dLRNRMTSGtfQpxwMjYgolJpbg5SouNxEk57bkuIiku50jjsj1E4DHoYKvKLzZJhglg16bRlyyVLEsPbCk9bA7h87n3eVupyO1aqjqFlWRzSrq%2bmL2744yzd7afdfCQ3iA700TOZrOdILFZHncOXKbggl3d2jtr%2fmWE; evt=*1YD4naks8XoliPm8l1HOgnZ%2fMVR%2brxElZb0ZH3AqPvjy00aGSWsjEV7N2yMxEGv6mFrO%2b5Qt4YBnZlADavsB%2bDw%3d%3d; udc=*1Z3JmtlfKLQPI8Kj%2bhFX5nbonq798hnGSd7H9b5cEUG6zS%2fnVwErgCJQjfXuQo4zX; udi=*1i5M4yCDfR9bz8niqJqh1qQ%3d%3d phpAds_partner3=eAFTNDKoMTQ2MbQ0NDa3sLAGsU1MDUyBbEVDHBIAKg8LcA%3D%3D PREF=ID=240bf4725279da0e:U=656d860421b7d298:FF=0:TM=1340809407:LM=1341477495:S=ZAu3CIypVcijK2z8; NID=61=c7mtIPXk0C1oNvhelwzTarx_LV7YA3zfAzRv50sqw1AmIVMnzNR0u-QGvvmZGjM9GyYBI3184EUIPOFk96Ctr978mi91k6k2a9PRco9Jt9Tld1twbJa7YfYR8FkH_kpU PREF=ID=daec698a6d335fac:U=e4f308a369f6afa1:FF=0:TM=1340180851:LM=1340180852:S=wqAY5KHZDDTgqG-C; NID=61=HEGjgaKRJQ4ULxldhgI-O0Qpk8-7SPvxMsmj6YsJeLQ2KthtQ6oZ09r5JbhpCmdW2cF7FMxk_gl5bYT-dpmjncR5Diws-rlEqoWLdkJKwNdjYXt8w5qvHPKO2E10GFJf RDC_VISITOR_ID=0159FE71-D18F-4066-B933-2FB39F961633; RDC_VISITE_ID_V2=AE905F80-150E-4A51-953C-D29BC24AB117; CFID=238634555; CFMAGIC=238634555%3A30294847; RDC_VISITE_ID=552456196; xtvrn=$308378$; etuid=HsfIsvrQ2KD7kdXuQNLNpg--; RDC_INTERSTITIAL=interstitiel; et=1; et0=9WEzt.Ng_QO_4I.lc2tpaxPhN.bxac5tD17LbNfUzr4nC2.0Ug0AF1WTcTz0hN3751KuxtXF_634DpnmdGPnrg7Uf3Q3MUaJkrG9GJQRZZgGVg7k890.QkT.vX.d2zM1uneeVpa7hMuMMDDpSQvEhK_jW1lBwfMhpe6flcfmRh4a8VeQbe9R.h18qGk08qt9; __utma=7226029.1048398946.1341913412.1341913412.1341913412.1; __utmb=7226029.4.9.1341913418164; __utmc=7226029; __utmz=7226029.1341913412.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) ruid=592cc2264ffbf9412effb00221957a^1^1341913409^788508674; rsid=CMuNRCnwr4RJFvOudUoCwqBpLKWcxgZprODTJBmN+jd4CMChZh/4S5wOdeVRmsAx2thOzx8Vu3HJcuIkd4IzUZBM4a4xIyWaasWi6suxAaxdPo9e; nus_2307=1.00; csi2=3298098.js^1^1341913410^1341913410&3282012.js^1^1341913409^1341913409; put_2307=eed09d9b-68a5-46c8-85e1-231e745057e7; put_2194=4918409058730637084; csi15=3322954.js^1^1341913779^1341913779; put_2249=CAESEAoWMbcI-VCjsyLJaWwAjEw; put_2245=9176626e-ca74-11e1-9043-00259035d4c0; ses9=16416^1; put_1512=4ffbf942-864c-a661-7ac0-39f6ab1a9717; put_2146=RUIDt4re5wury138c7dwqcq8e7q13tm1pfwijjwfh9zohtp5zekq1jyo%3D%3D%3D%3D; put_2309=RUIDt4re5wury138c7dwqcq8e7q13tm1pfwijjwfh9zohtp5zekq1jyo%3D%3D%3D%3D; put_2211=4612108434589598973; put_2149=2c03d2f2-cc75-449e-9d9f-2a0002ae6603; ses15=14319^3&16416^1; rdk=8475/13710; ses2=13710^2; put_1986=1895376179915936457; put_1430=2682edfe-500d-4496-87b9-a7253582a8f9; au=H4GSTRKR-5HPK-10.42.9.189; put_2596=638666722680058483; put_2025=40430961-c3df-4dce-baf2-cf7776d6f3ac; cd=false; lm=\ sasd=%24a%3D0t%3B%24cn%3D0%5F0%3B%24isp%3D0%3B%24qc%3D1310896006%3B%24ql%3Dunknown%3B%24qpc%3D75001%3B%24qpp%3D0%3B%24qt%3D184%5F1903%5F42652t; vs=13992=5009023; TestIfCookie=ok; TestIfCookieP=ok; pbwmaj6=y; pbw=%24b%3D16999%3B%24o%3D99999%3B%24sh%3D1024%3B%24sw%3D1600; dyncdn=7; pdomid=60; pid=6225401355325924155 session-token=7D0Zg+vD5hA+HmZhHNW0JdZh7EVDw7g5rfIBzLxWNHwuOOcI4pw7V8R37ePBlfF/XSCdbvX/92dXFLOg1GQqYW0Nq+rpHH91uXHByaGzSS5RpQ/L9dZhtKKGXWyJxmTHDoNYw8nNUC4sMO3jyVT4ll3BzGoGYF1ZYZPiZXD0m/mSc1oJmMkLlCHX6rw0fwbISjKFANUrWiu8i/3GSQSuoFb6peqoXp6OirSVgGlmDeC0D5GZCAHJEFWnt15B7QSPGC09oAa8y4c=; csm-hit=420.46; ubid-acbfr=275-1998587-8474020; session-id-time=2082754801l; session-id=277-5453710-9941953 U=63B9CAB9A0C18D5102C9D3C76F1B1756; V=3; D0=@f^ku^FABf^ku^FAD>>^>>; K=@@GF_zDCB>?Vu@? UID=2153fb78-2.22.48.98-1340901578; UIDR=1340901578 uid=7992a8c86b636fd6248a20093720bf05; pme=S7QysKquBQA%3D; pma=XdhJjhw5DAXQu%2FgECg0UlX2aAnrjtZdG371VBozky1rlL4rT56CI%2BHo9r98%2FX%2B2fr%2B8fv17j9ePr318%2FLpzP%2BZY8rY2L2uv3f3%2FALOBBcqqkVfDUY03UQRjEV0eUFWAQe88CBWiD3hb72958%2Fzf1MkHVTTk3y%2B9A%2Fznov9mab4EaXSRtWpNEkm4k3aDng9QGMnpJxt%2FzZqZT3v5Z3h5VFgP0gPDXNzY5mRUNTo5SpYtmPflg5ekgTxLZg7%2BOXs8BqrH0pcyoE1RPDuIcs4Ow2ZF1qpKdbDuxBMhYqizIdtb6zV5ZmqODlO1WkUzAdZhttTlylvzGqZyNU%2Bs3Owg%2Bpz0xyW%2BJUpud%2FCoTjdyp9D15yB0rtXvmpO7rg5dqs32grFZq%2FeasJ59u7gmDZU98s%2FuAatQdPp0Hazup5ppUM%2FVQaruoylqiamVFAymr3lcEsqgyZuXKCi9rY2XXqFfiPfFwYCnrjpzozcOsnCMiTjw0ugcmJnM791SvVHqxFRebbzE5ayiDiXFq11GxmdRvWE080PPL%2BXMCtgxOOWugIPfqgU5ezO2aVCXSag5s1t5lxpY70oz2B4NMAJHN2j2LmV7TqGsnB%2F0S2Axm86JVUbUZ1OiiqvfULRzwGWyGgJfg3gz6LKhRcE8H99hFsyKyfYKTeH%2BmsgDtOtN0a8L8%2BbCZFZEDd06w3YI5CuvHhr5oghZVqR3Jbl3s8qCvr161ydxeRC9Ro2EO1eamP%2FeoVjbds9nJm5mOjQc22Ob%2BW%2BqxaePUXb65p%2FeIRWRVxrzvHRObVcb%2B3HT5ZqPs8eFdVKNmT8TByiO7IDnjRgj2Zxz5JAcmbk95cRdgc9lZZBRGRu7N%2FOgX9meklcZmml%2F1vtkvmwnYTM62z9Lc67a5qHrQH%2FXbPAnsM%2FVX9bgRNvldVPVgd4cnzQF%2FPKNcPWST%2FJjUrPfDRRuUoFPRauQuE3ggI3bWduKcaafj1P2Z9nXqr279Gycnq81slcHkXkmmOJnizPLG%2Fm2lyh5RfR9L7o6LFnrKSh2S2zfZPTk%2B9PQ%2Bq15HD8Sb%2FuW68sKMJVsjl6j22UU1FjZDsl%2BSnZzsutzoZfmucSMjW26LpLPy1K8HyVPQjaVmy8RlfMQ56ILqnbs%2FU%2B%2F44xZNdsFpH6hEfcaoMtg9fI059Nmh0ocnzmtlVyvocf8dnsFO%2FYL2bWUgqx64N%2B%2FJU08ioz8PXXf4jnKZaDUj%2FHEHHCp9eLJKN8qJ4OQm6gUKYpmgrCfrt6Ar62SEHtUcU5vkTn7spcO3izM%2BcqfuzaokJ4McQNOq4H3Qrdad3BcnJ0xM9frffrl%2F%2FwM%3D; pmc2=MzBAAoYGgwkAAA%3D%3D __utma=249856005.1255122414.1341913408.1341913408.1341913408.1; __utmb=249856005.1.10.1341913408; __utmc=249856005; __utmz=249856005.1341913408.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __gads=ID=21a9c3493f59687e:T=1341913408:S=ALNI_MafqLep2U9d_eVnuZkPO5RZukWBtA vs=13992=5009023; TestIfCookie=ok; TestIfCookieP=ok; pbwmaj6=y; pbw=%24b%3D16999%3B%24o%3D99999%3B%24sh%3D1024%3B%24sw%3D1600; dyncdn=7; sasd=%24a%3D0t%3B%24cn%3D0%5F0%3B%24isp%3D0%3B%24qc%3D1310896006%3B%24ql%3Dunknown%3B%24qpc%3D75001%3B%24qpp%3D0%3B%24qt%3D184%5F1903%5F42652t; pdomid=60; pid=6225401355325924155 yaws-2.0.2/test/eunit/copy_error_log.erl0000664000175000017500000000116412605311413015252 00000000000000%% coding: utf-8 -module(copy_error_log). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). -include("yaws_api.hrl"). -include("tftest.hrl"). %% ignore it error_log_handler_test() -> ?assertMatch({ok, _}, yaws_log:start_link()), GConf = yaws:create_gconf([], default), SConf = yaws:create_sconf(".", []), ?assertEqual(ok, yaws_log:setup(GConf, [SConf])), Handlers = gen_event:which_handlers(error_logger), ?assert(lists:member(yaws_log_file_h, Handlers)), Dir = yaws:gconf_logdir(GConf), File = filename:join([Dir, "report.log"]), ?assert(filelib:is_regular(File)), ok. yaws-2.0.2/test/eunit/cookies.erl0000664000175000017500000002672412605311413013673 00000000000000-module(cookies). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). -include("yaws_api.hrl"). -include("tftest.hrl"). parse_set_cookies_test() -> %% Set-Cookie: value ?assertEqual( #setcookie{key="value"}, yaws_api:parse_set_cookie("value") ), %% Set-Cookie: name=value ?assertEqual( #setcookie{key="name", value="value"}, yaws_api:parse_set_cookie("name=value") ), %% Set-Cookie: name="value [quoted]" ?assertEqual( #setcookie{key="name", value="value [quoted]", quoted=true}, yaws_api:parse_set_cookie("name=\"value [quoted]\"") ), %% Set-Cookie: name=value; path=/ ?assertEqual( #setcookie{key="name", value="value", path="/"}, yaws_api:parse_set_cookie("name=value; Path=/") ), %% Set-Cookie: name=value; domain=test.com ?assertEqual( #setcookie{key="name", value="value", domain="test.com"}, yaws_api:parse_set_cookie("name=value; Domain=test.com") ), %% Set-Cookie: name=value; max-age=86400 ?assertEqual( #setcookie{key="name", value="value", max_age="86400"}, yaws_api:parse_set_cookie("name=value; Max-Age=86400") ), %% Set-Cookie: name=value; expires="Sat, 02 May 2009 23:38:25 GMT" ?assertEqual( #setcookie{key="name", value="value", expires="Sat, 02 May 2009 23:38:25 GMT"}, yaws_api:parse_set_cookie("name=value; Expires=Sat, 02 May 2009 23:38:25 GMT") ), %% Set-Cookie: name=value; secure ?assertEqual( #setcookie{key="name", value="value", secure=true}, yaws_api:parse_set_cookie("name=value; Secure") ), %% Set-Cookie: name=value; HttpOnly ?assertEqual( #setcookie{key="name", value="value", http_only=true}, yaws_api:parse_set_cookie("name=value; HttpOnly") ), %% Set-Cookie: name=value; comment="This is a comment" ?assertEqual( #setcookie{key="name", value="value", extensions=[{"comment", "This is a comment", true}]}, yaws_api:parse_set_cookie("name=value; Comment=\"This is a comment\"") ), %% Set-Cookie: name=value; discard ?assertEqual( #setcookie{key="name", value="value", extensions=[{"discard", undefined, false}]}, yaws_api:parse_set_cookie("name=value; discard") ), %% Set-Cookie: name=value; ext1=val1; ext2="val2"; ext3 ?assertEqual( #setcookie{key="name", value="value", extensions=[{"ext1", "val1", false}, {"ext2", "val2", true}, {"ext3", undefined, false}]}, yaws_api:parse_set_cookie("name=value; ext1=val1; ext2=\"val2\"; ext3") ), %% Set-Cookie: value1, value2, name=value ?assertEqual( [#setcookie{key="value1"}, #setcookie{key="value2"}, #setcookie{key="name", value="value"}], yaws_api:parse_set_cookie("value1 , value2, name=value") ), ok. parse_cookies_test() -> %% Cookie: value ?assertEqual( [#cookie{key="value"}], yaws_api:parse_cookie("value") ), %% Cookie: name=value ?assertEqual( [#cookie{key="name", value="value"}], yaws_api:parse_cookie("name=value") ), %% Cookie: name="value [quoted]" ?assertEqual( [#cookie{key="name", value="value [quoted]", quoted=true}], yaws_api:parse_cookie("name=\"value [quoted]\"") ), %% Cookie: name=value; $path=/ ?assertEqual( [#cookie{key="name", value="value"}, #cookie{key="$path", value="/"}], yaws_api:parse_cookie("name=value; $path=/") ), %% Cookie: name=value; $port=443 ?assertEqual( [#cookie{key="name", value="value"}, #cookie{key="$port", value="443"}], yaws_api:parse_cookie("name=value; $port=443") ), %% Cookie: name=value; $domain=test.com ?assertEqual( [#cookie{key="name", value="value"}, #cookie{key="$domain", value="test.com"}], yaws_api:parse_cookie("name=value; $domain=test.com") ), %% Cookie: $version=1, value1, value2; name=value ?assertEqual( [#cookie{key="$version", value="1"}, #cookie{key="value1"}, #cookie{key="value2"}, #cookie{key="name", value="value"}], yaws_api:parse_cookie("$version=1, value1, value2; name=value") ), ok. parse_invalid_set_cookies_test() -> ?assertEqual([], yaws_api:parse_set_cookie("name=value [quoted]")), ?assertEqual([], yaws_api:parse_set_cookie("name1=value1 name2=value2")), ?assertEqual([], yaws_api:parse_set_cookie("name1=value1 domain=test.com path=/")), ?assertEqual([], yaws_api:parse_set_cookie("name=value; secure=1")), ok. parse_invalid_cookies_test() -> ?assertEqual([], yaws_api:parse_cookie("name=value [quoted]")), ?assertEqual([], yaws_api:parse_cookie("name1=value1 name2=value2")), ok. format_set_cookies_test() -> %% Set-Cookie: value ?assertEqual( "value", lists:flatten( yaws_api:format_set_cookie( #setcookie{key="value"} ) ) ), %% Set-Cookie: name=value ?assertEqual( "name=value", lists:flatten( yaws_api:format_set_cookie( #setcookie{key="name", value="value"} ) ) ), %% Set-Cookie: name="value [quoted]" ?assertEqual( "name=\"value [quoted]\"", lists:flatten( yaws_api:format_set_cookie( #setcookie{key="name", value="value [quoted]", quoted=true} ) ) ), %% Set-Cookie: name=value; Domain=test.com; Max-Age=86400; %% Expires=Sat, 02 May 2009 23:38:25 GMT; %% Secure; HttpOnly; Path=/; Port=443; %% Comment="This is a comment"; %% CommentURL="http://localhost" ?assertEqual( "name=value; Domain=test.com; Max-Age=86400; " "Expires=Sat, 02 May 2009 23:38:25 GMT; Secure; HttpOnly; " "path=/; port=443; " "comment=\"This is a comment\"; commenturl=\"http://localhost\"", lists:flatten( yaws_api:format_set_cookie( #setcookie{key="name", value="value", domain="test.com", max_age="86400", expires="Sat, 02 May 2009 23:38:25 GMT", secure=true, http_only=true, extensions=[{"path", "/", false}, {"port", "443", false}, {"comment", "This is a comment", true}, {"commenturl", "http://localhost", true}]} ) ) ), ok. format_cookies_test() -> %% Cookie: value ?assertEqual( "value", lists:flatten( yaws_api:format_cookie(#cookie{key="value"}) ) ), %% Cookie: name=value ?assertEqual( "name=value", lists:flatten( yaws_api:format_cookie(#cookie{key="name", value="value"}) ) ), %% Cookie: name="value [quoted]" ?assertEqual( "name=\"value [quoted]\"", lists:flatten( yaws_api:format_cookie( #cookie{key="name", value="value [quoted]", quoted=true} ) ) ), %% Cookie: value1; value2; name=value ?assertEqual( "value1; value2; name=value", lists:flatten( yaws_api:format_cookie([#cookie{key="value1"}, #cookie{key="value2"}, #cookie{key="name", value="value"}]) ) ), ok. get_multiple_cookies_test() -> ?assertEqual("1234", yaws_api:find_cookie_val("abc", ["abc=1234;def=5678"])), ?assertEqual("5678", yaws_api:find_cookie_val("def", ["abc=1234;def=5678"])), ?assertEqual([], yaws_api:find_cookie_val("ghij", ["abc=1234;def=5678"])), ok. cookie_key_case_insensitive_test() -> ?assertEqual("1234", yaws_api:find_cookie_val("abc", ["abc=1234"])), ?assertEqual("1234", yaws_api:find_cookie_val("abc", ["ABC=1234"])), ?assertEqual("1234", yaws_api:find_cookie_val("AbC", ["aBc=1234"])), ok. set_cookie_expires_test() -> %% rfc1123 date format ?assertEqual( #setcookie{key="a", value="b", expires="Sat, 02 May 2009 23:38:25 GMT"}, yaws_api:parse_set_cookie("a=b; Expires=Sat, 02 May 2009 23:38:25 GMT") ), %% rfc1123 date format with hyphens ?assertEqual( #setcookie{key="a", value="b", expires="Sat, 02-May-2009 23:38:25 GMT"}, yaws_api:parse_set_cookie("a=b; Expires=Sat, 02-May-2009 23:38:25 GMT") ), %% rfc1036 date format ?assertEqual( #setcookie{key="a", value="b", expires="Saturday, 02-May-2009 23:38:25 GMT"}, yaws_api:parse_set_cookie("a=b; Expires=Saturday, 02-May-2009 23:38:25 GMT") ), %% AINSI C's astime format: must be in double quotes ?assertEqual( #setcookie{key="a", value="b", expires="Sat May 2 23:38:25 2009"}, yaws_api:parse_set_cookie("a=b; Expires=\"Sat May 2 23:38:25 2009\"") ), ok. real_cookies_test() -> {ok, Io} = file:open(?srcdir ++ "/cookies.dump", read), %% {error, _} -> %% %% handle eunit testing under rebar %% file:open("../test/eunit/cookies.dump", read); %% Else -> %% Else %% end, ?assertEqual(ok, parse_cookies(Io, file:read_line(Io), 1)), ok. real_setcookies_test() -> {ok, Io} = file:open(?srcdir ++ "/setcookies.dump", read), %% {error, _} -> %% %% handle eunit testing under rebar %% file:open("../test/eunit/setcookies.dump", read); %% Else -> %% Else %% end, ?assertEqual(ok, parse_set_cookies(Io, file:read_line(Io), 1)), ok. set_cookie_test() -> ?assertEqual( "a=bcd; Version=1; Comment=OK; Domain=g.com; Path=/; Max-Age=1; " "Expires=Tue, 03 Jan 2012 10:00:05 GMT; HttpOnly; Secure", begin {header, {set_cookie, L}} = yaws_api:set_cookie("a", "bcd", [{expires, {{2012,1,3},{10,0,5}}}, {max_age, 1}, secure, http_only, {path, "/"}, {domain, "g.com"}, {comment, "OK"}]), lists:flatten(L) end), ?assertEqual( "a=bcd; Version=1; Path=/home", begin {header, {set_cookie, L}} = yaws_api:set_cookie("a", "bcd", [{path, "/home"}]), lists:flatten(L) end), ?assertEqual( "a=bcd; Version=1", begin {header, {set_cookie, L}} = yaws_api:set_cookie("a", "bcd", []), lists:flatten(L) end). parse_cookies(Io, eof, _) -> file:close(Io), ok; parse_cookies(Io, {error, Reason}, LNo) -> file:close(Io), {error, Reason, LNo}; parse_cookies(Io, {ok, Line0}, LNo) -> Line = string:strip(Line0, right, $\n), Cookies = yaws_api:parse_cookie(Line), ?assertMatch({LNo, [C|_]} when is_record(C, cookie), {LNo, Cookies}), ?assertEqual( string:to_lower(Line), string:to_lower(lists:flatten(yaws_api:format_cookie(Cookies))) ), parse_cookies(Io, file:read_line(Io), LNo+1). parse_set_cookies(Io, eof, _) -> file:close(Io), ok; parse_set_cookies(Io, {error, Reason}, LNo) -> file:close(Io), {error, Reason, LNo}; parse_set_cookies(Io, {ok, Line0}, LNo) -> Line = string:strip(Line0, right, $\n), SetCookie = yaws_api:parse_set_cookie(Line), ?assertMatch({LNo, C} when is_record(C, setcookie), {LNo, SetCookie}), ?assertEqual( string:to_lower(string:substr(Line, 1, string:chr(Line, $=)-1)), SetCookie#setcookie.key ), parse_set_cookies(Io, file:read_line(Io), LNo+1). yaws-2.0.2/test/eunit/ipmask.erl0000664000175000017500000001542012605311413013512 00000000000000-module(ipmask). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). -include("tftest.hrl"). parse_ipmask_test() -> ?assertEqual({127,0,0,1}, yaws:parse_ipmask("127.0.0.1")), ?assertEqual({0,0,0,0,0,0,0,1}, yaws:parse_ipmask("::1")), ?assertThrow({error, einval}, yaws:parse_ipmask("invalid")), ?assertThrow({error, einval}, yaws:parse_ipmask(invalid)), ?assertThrow({error, einval}, yaws:parse_ipmask("127.0.0.500")), ?assertThrow({error, einval}, yaws:parse_ipmask("::ZZ")), ?assertEqual({127,0,0,1}, yaws:parse_ipmask("127.0.0.1/32")), ?assertEqual({0,0,0,0,0,0,0,1}, yaws:parse_ipmask("::1/128")), ?assertEqual({{127,0,0,1}, {127,0,0,254}}, yaws:parse_ipmask("127.0.0.1/24")), ?assertEqual({{127,0,0,1}, {127,0,0,254}}, yaws:parse_ipmask("127.0.0.1/255.255.255.0")), ?assertEqual({{127,0,0,1}, {127,255,255,254}}, yaws:parse_ipmask("127.0.0.0/8")), ?assertEqual({{192,168,0,1}, {192,171,255,254}}, yaws:parse_ipmask("192.168.4.2/14")), ?assertEqual({{192,168,4,1}, {192,168,4,126}}, yaws:parse_ipmask("192.168.4.2/25")), ?assertEqual({{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,16#ffff}}, yaws:parse_ipmask("::1/112")), ?assertEqual({{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,16#ffff}}, yaws:parse_ipmask("::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:0")), ?assertEqual({{0,0,0,0,0,0,0,0}, {0,0,0,0,16#ffff,16#ffff,16#ffff,16#ffff}}, yaws:parse_ipmask("::1/64")), ?assertEqual({{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,16#003f}}, yaws:parse_ipmask("::1/122")), ?assertThrow({error, einval}, yaws:parse_ipmask("127.0.0.1/36")), ?assertThrow({error, einval}, yaws:parse_ipmask("127.0.0.1/256.0.0.0")), ?assertThrow({error, einval}, yaws:parse_ipmask("::1/::fffg")), ok. match_ipmask_test() -> ?assertEqual(true, yaws:match_ipmask({127,0,0,1}, {127,0,0,1})), ?assertEqual(true, yaws:match_ipmask({0,0,0,0,0,0,0,1}, {0,0,0,0,0,0,0,1})), ?assertEqual(false,yaws:match_ipmask({127,0,0,2}, {127,0,0,1})), ?assertEqual(false,yaws:match_ipmask(undefined, {127,0,0,1})), ?assertEqual(false,yaws:match_ipmask({127,0,0,1}, {0,0,0,0,0,0,0,1})), ?assertEqual(true, yaws:match_ipmask({192,168,1,10}, {{192,168,1,10}, {192,168,1,20}})), ?assertEqual(false,yaws:match_ipmask({192,168,1,30}, {{192,168,1,10}, {192,168,1,20}})), ?assertEqual(true, yaws:match_ipmask({192,168,1,30}, {{192,168,1,0}, {192,168,2,0}})), ?assertEqual(false,yaws:match_ipmask({192,168,2,10}, {{192,168,1,0}, {192,168,2,0}})), ?assertEqual(true, yaws:match_ipmask({192,168,1,10}, {{192,168,0,0}, {192,169,0,0}})), ?assertEqual(true, yaws:match_ipmask({192,168,2,10}, {{192,168,0,0}, {192,169,0,0}})), ?assertEqual(false,yaws:match_ipmask({192,169,2,10}, {{192,168,0,0}, {192,169,0,0}})), ?assertEqual(true, yaws:match_ipmask({192,168,2,10}, {{192,0,0,0}, {193,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({192,169,2,10}, {{192,0,0,0}, {193,0,0,0}})), ?assertEqual(false,yaws:match_ipmask({193,169,2,10}, {{192,0,0,0}, {193,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({0,0,0,0,0,0,0,1}, {{0,0,0,0,0,0,0,1}, {0,0,0,0,0,0,0,2}})), ?assertEqual(false,yaws:match_ipmask({0,0,0,0,0,0,0,3}, {{0,0,0,0,0,0,0,1}, {0,0,0,0,0,0,0,2}})), ?assertEqual(true, yaws:match_ipmask({0,0,0,0,0,0,1,0}, {{0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,2,0}})), ?assertEqual(true, yaws:match_ipmask({0,0,0,0,0,0,1,3}, {{0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,2,0}})), ?assertEqual(false,yaws:match_ipmask({0,0,0,0,0,0,3,0}, {{0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,2,0}})), ?assertEqual(true, yaws:match_ipmask({0,0,0,0,0,1,0,0}, {{0,0,0,0,0,1,0,0}, {0,0,0,0,0,2,0,0}})), ?assertEqual(true, yaws:match_ipmask({0,0,0,0,0,1,3,0}, {{0,0,0,0,0,1,0,0}, {0,0,0,0,0,2,0,0}})), ?assertEqual(false, yaws:match_ipmask({0,0,0,0,0,3,0,0}, {{0,0,0,0,0,1,0,0}, {0,0,0,0,0,2,0,0}})), ?assertEqual(true, yaws:match_ipmask({0,0,0,0,1,0,0,0}, {{0,0,0,0,1,0,0,0}, {0,0,0,0,2,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({0,0,0,0,1,3,0,0}, {{0,0,0,0,1,0,0,0}, {0,0,0,0,2,0,0,0}})), ?assertEqual(false,yaws:match_ipmask({0,0,0,0,3,0,0,0}, {{0,0,0,0,1,0,0,0}, {0,0,0,0,2,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({0,0,0,1,0,0,0,0}, {{0,0,0,1,0,0,0,0}, {0,0,0,2,0,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({0,0,0,1,3,0,0,0}, {{0,0,0,1,0,0,0,0}, {0,0,0,2,0,0,0,0}})), ?assertEqual(false,yaws:match_ipmask({0,0,0,3,0,0,0,0}, {{0,0,0,1,0,0,0,0}, {0,0,0,2,0,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({0,0,1,0,0,0,0,0}, {{0,0,1,0,0,0,0,0}, {0,0,2,0,0,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({0,0,1,3,0,0,0,0}, {{0,0,1,0,0,0,0,0}, {0,0,2,0,0,0,0,0}})), ?assertEqual(false,yaws:match_ipmask({0,0,3,0,0,0,0,0}, {{0,0,1,0,0,0,0,0}, {0,0,2,0,0,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({0,1,0,0,0,0,0,0}, {{0,1,0,0,0,0,0,0}, {0,2,0,0,0,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({0,1,3,0,0,0,0,0}, {{0,1,0,0,0,0,0,0}, {0,2,0,0,0,0,0,0}})), ?assertEqual(false,yaws:match_ipmask({0,3,0,0,0,0,0,0}, {{0,1,0,0,0,0,0,0}, {0,2,0,0,0,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({1,0,0,0,0,0,0,0}, {{1,0,0,0,0,0,0,0}, {2,0,0,0,0,0,0,0}})), ?assertEqual(true, yaws:match_ipmask({1,3,0,0,0,0,0,0}, {{1,0,0,0,0,0,0,0}, {2,0,0,0,0,0,0,0}})), ?assertEqual(false,yaws:match_ipmask({3,0,0,0,0,0,0,0}, {{1,0,0,0,0,0,0,0}, {2,0,0,0,0,0,0,0}})), ok. yaws-2.0.2/test/eunit/multipart_post_parsing.erl0000664000175000017500000002360012605311413017036 00000000000000-module(multipart_post_parsing). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). -include("yaws_api.hrl"). -include("tftest.hrl"). data_to_parse() -> list_to_binary( ["--!!!\r\n", "Content-Disposition: form-data; name=\"abc123\"; " ++ "filename=\"abc123\"\r\n" ++ "Content-Type: text/plain\r\n" ++ "Test-Header: sampledata\r\n\r\n", "sometext\n\r\n--!!!--\r\n"]). complete_parse(Opt) -> yaws_api:parse_multipart_post(mk_arg(data_to_parse()), [Opt]). test_complete_parse(Opt) -> {result, Params} = complete_parse(Opt), 2 = length(Params), {"abc123", HeadParams} = proplists:get_value(head, Params), 4 = length(HeadParams), "abc123" = proplists:get_value("name", HeadParams), "abc123" = proplists:get_value("filename", HeadParams), "text/plain" = proplists:get_value(content_type, HeadParams), "sampledata" = proplists:get_value("test-header", HeadParams), proplists:get_value(body, Params). complete_parse_list_test() -> "sometext\n" = test_complete_parse(list), ok. complete_parse_binary_test() -> <<"sometext\n">> = test_complete_parse(binary), ok. test_incomplete_body(Opt) -> Data1 = list_to_binary( ["--!!!\r\n", "Content-Disposition: form-data; name=\"abc123\"; " ++ "filename=\"abc123\"\r\n\r\n", "someincomplete"]), A1 = mk_arg(Data1), {cont, Cont, Res1} = yaws_api:parse_multipart_post(A1, [Opt]), Data2 = list_to_binary( ["text\n\r\n--!!!\r\n", "Content-Disposition: form-data; name=\"def456\"; " ++ "filename=\"def456\"\r\n\r\n", "sometext\n\r\n--!!!--\r\n"]), A2 = A1#arg{cont = Cont, clidata = Data2}, {result, Res2} = yaws_api:parse_multipart_post(A2, [Opt]), 2 = length(Res1), {"abc123", HeadParams1} = proplists:get_value(head, Res1), PB = proplists:get_value(part_body, Res1), 2 = length(HeadParams1), "abc123" = proplists:get_value("filename", HeadParams1), "abc123" = proplists:get_value("name", HeadParams1), 3 = length(Res2), {"def456", HeadParams2} = proplists:get_value(head, Res2), BL = lists:sort([B || {K, _}=B <- Res2, K =:= body]), 2 = length(HeadParams2), "def456" = proplists:get_value("filename", HeadParams2), "def456" = proplists:get_value("name", HeadParams2), {PB, BL}. incomplete_body_list_test() -> {"someinc", [{body, "ompletetext\n"}, {body, "sometext\n"}]} = test_incomplete_body(list). incomplete_body_binary_test() -> {<<"someinc">>, [{body, <<"ompletetext\n">>}, {body, <<"sometext\n">>}]} = test_incomplete_body(binary). test_incomplete_head_list(Opt) -> Data1 = list_to_binary( ["--!!!\r\n", "Content-Disposition: form-data; name=\"abc123\"; " ++ "filename=\"abc123\"\r\n\r\n", "sometext1\n\r\n--!!!\r\n", "Content-Disposition: form-data; name=\"ghi"]), A1 = mk_arg(Data1), {cont, Cont, Res1} = yaws_api:parse_multipart_post(A1, [Opt]), Data2 = list_to_binary( ["789\"; " ++ "filename=\"ghi789\"\r\n\r\n", "sometext2\n\r\n--!!!--\r\n"]), A2 = A1#arg{cont = Cont, clidata = Data2}, {result, Res2} = yaws_api:parse_multipart_post(A2), 2 = length(Res1), {"abc123", HeadParams1} = proplists:get_value(head, Res1), Body1 = proplists:get_value(body, Res1), 2 = length(HeadParams1), "abc123" = proplists:get_value("filename", HeadParams1), "abc123" = proplists:get_value("name", HeadParams1), 2 = length(Res2), {"ghi789", HeadParams2} = proplists:get_value(head, Res2), Body2 = proplists:get_value(body, Res2), 2 = length(HeadParams1), "ghi789" = proplists:get_value("filename", HeadParams2), "ghi789" = proplists:get_value("name", HeadParams2), {Body1, Body2}. incomplete_head_list_test() -> {"sometext1\n", "sometext2\n"} = test_incomplete_head_list(list), ok. incomplete_head_binary_test() -> {<<"sometext1\n">>, <<"sometext2\n">>} = test_incomplete_head_list(binary), ok. boundary_markers_test() -> Body = <<"------WebKitFormBoundaryUkx0KS47IKKfcF4z\r\n", "Content-Disposition: form-data; name=upfile; filename=test.txt\r\n", "Content-Type: text/plain\r\n", "\r\n", "Hello world\n", "\r\n", "------WebKitFormBoundaryUkx0KS47IKKfcF4z\r\n", "Content-Disposition: form-data; name=note\r\n", "\r\n", "test\r\n", "------WebKitFormBoundaryUkx0KS47IKKfcF4z--\r\n">>, Results = lists:foldl(fun (N, {Ok, Errors, Done}) -> <> = Body, case boundary_marker_parse(BodyPart) of {cont, _, _} -> {Ok+1, Errors, Done}; {result, _} -> {Ok+1, Errors, Done+1}; _ -> {Ok, Errors+1, Done} end end, {0, 0, 0}, lists:seq(1, size(Body))), ?assertMatch({_, 0, 1}, Results). boundary_marker_parse(Body) -> Arg = #arg{headers=#headers{content_type="multipart/form-data; boundary=----WebKitFormBoundaryUkx0KS47IKKfcF4z"}, req=#http_request{method='POST'}, clidata=Body}, yaws_api:parse_multipart_post(Arg). test_incomplete_boundary_list(Opt) -> Data1 = list_to_binary( ["--!!!\r\n", "Content-Disposition: form-data; name=\"abc123\"; " ++ "filename=\"abc123\"\r\n\r\n", "sometext1\n\r\n--!!!"]), A1 = mk_arg(Data1), {cont, Cont1, Res1} = yaws_api:parse_multipart_post(A1, [Opt]), Data2 = list_to_binary( ["\r\nContent-Disposition: form-data; name=\"ghi789\"; " ++ "filename=\"ghi789\"\r\n\r\n", "sometext2\n\r\n--!!!"]), A2 = A1#arg{cont = Cont1, clidata = Data2}, {cont, Cont2, Res2} = yaws_api:parse_multipart_post(A2), Data3 = <<"--\r\n">>, A3 = A2#arg{cont = Cont2, clidata = Data3}, {result, []} = yaws_api:parse_multipart_post(A3), 2 = length(Res1), {"abc123", HeadParams1} = proplists:get_value(head, Res1), Body1 = proplists:get_value(body, Res1), 2 = length(HeadParams1), "abc123" = proplists:get_value("filename", HeadParams1), "abc123" = proplists:get_value("name", HeadParams1), 2 = length(Res2), {"ghi789", HeadParams2} = proplists:get_value(head, Res2), Body2 = proplists:get_value(body, Res2), 2 = length(HeadParams1), "ghi789" = proplists:get_value("filename", HeadParams2), "ghi789" = proplists:get_value("name", HeadParams2), {Body1, Body2}. incomplete_boundary_list_test() -> {"sometext1\n", "sometext2\n"} = test_incomplete_boundary_list(list), ok. incomplete_boundary_binary_test() -> {<<"sometext1\n">>, <<"sometext2\n">>} = test_incomplete_boundary_list(binary), ok. read_multipart_form_base(Opt) -> {done, Dict} = yaws_multipart:read_multipart_form(mk_arg(data_to_parse()), [no_temp_file, Opt]), {ok, Params} = dict:find("abc123", Dict), "abc123" = proplists:get_value("filename", Params), "text/plain" = proplists:get_value(content_type, Params), "sampledata" = proplists:get_value("test-header", Params), proplists:get_value(value, Params). read_multipart_form_list_test() -> "sometext\n" = read_multipart_form_base(list), ok. read_multipart_form_binary_test() -> <<"sometext\n">> = read_multipart_form_base(binary), ok. malformed_multipart_form_test() -> Data1 = list_to_binary( ["--!!!\r\n", "Content-Disposition: form-data; name=\"abc123\"; " ++ "filename=\"abc123\"\r\n\r\n", "sometext\n\r\n--!!!Oops"]), A1 = mk_arg(Data1), {error, malformed_multipart_post} = yaws_api:parse_multipart_post(A1), Data2 = list_to_binary( ["--!!!\r\n", "Content-Disposition: form-data; name=\"abc123\"; " ++ "filename=\"abc123\"\r\n", "Invalid-Header\r\n\r\n" "sometext\n\r\n--!!!"]), A2 = mk_arg(Data2), {error, malformed_multipart_post} = yaws_api:parse_multipart_post(A2), Req = #http_request{method = 'POST'}, Hdrs1 = #headers{}, Hdrs2 = #headers{content_type = "text/plain"}, A3 = #arg{headers=Hdrs1, req=Req}, {error, no_content_type} = yaws_api:parse_multipart_post(A3), A4 = #arg{headers=Hdrs2, req=Req}, {error, no_multipart_form_data} = yaws_api:parse_multipart_post(A4), ok. escaped_data_to_parse(Name) -> list_to_binary( ["--!!!\r\n", "Content-Disposition: form-data; name=\"" ++ Name ++ "\"\r\n\r\n" "sometext\n\r\n--!!!--\r\n"]). get_unescaped_name(RawName) -> Data = escaped_data_to_parse(RawName), {result, Params} = yaws_api:parse_multipart_post(mk_arg(Data)), 2 = length(Params), {Name, HeadParams} = proplists:get_value(head, Params), [{"name", Name}] = HeadParams, Name. escaped_parse_test() -> %% Support both escaped (Firefox, Opera) and unescaped (Konqueror) %% quotation mark. "a\"b" = get_unescaped_name("a\\\"b"), "a\"b" = get_unescaped_name("a\"b"), %% Do not decode "%22" (IE, Chrome), user must deal with ambiguity %% himself. "a%22b" = get_unescaped_name("a%22b"), %% Support unescaped backslash (Firefox, Chrome, Konqueror, IE). "a\\b" = get_unescaped_name("a\\b"), "a\\\\b" = get_unescaped_name("a\\\\b"), %% Support backslash at the end of name (for simple form values). "a\\" = get_unescaped_name("a\\"), ok. mk_arg(Data) -> ContentType = "multipart/form-data; boundary=!!!", Req = #http_request{method = 'POST'}, Headers = #headers{content_type = ContentType}, #arg{headers = Headers, req = Req, clidata = Data}. yaws-2.0.2/test/eunit/Makefile.am0000664000175000017500000000166112605311413013560 00000000000000include @top_srcdir@/include.mk MODULES = multipart_post_parsing.erl \ yaws_session_server_test.erl \ ehtml_test.erl \ cookies.erl \ headers.erl \ ipmask.erl \ gconf.erl \ sconf.erl \ yaws_rpc_test.erl \ proc_cleanup.erl \ subconfig.erl \ copy_error_log.erl EXTRA_DIST = $(MODULES) cookies.dump setcookies.dump subconfig_DATA EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) client.log check-local: $(EBIN_FILES) $(top_builddir)/test/src/test.beam quiet-stop wait-stopped @echo @echo " ==== EUNIT TESTS ==== " @echo $(AM_V_at)$(ERL) $(ERL_GENERIC_FLAGS) -noshell -s test run $(MODULES:.erl=) distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/t11/0000775000175000017500000000000012605312015011060 500000000000000yaws-2.0.2/test/t11/Makefile.in0000664000175000017500000003644012605311446013063 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t11 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl EXTRA_DIST = $(MODULES) src EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t11/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t11/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test prepare-test:: $(AM_V_at)$(INSTALL) -d include $(AM_V_at)echo "-define(SRCDIR_VERSION, \"1.0\")." > include/srcdir_test.hrl clean-test:: $(AM_V_at)rm -fr include distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t11/app_test.erl0000664000175000017500000000371012605311413013325 00000000000000-module(app_test). -compile(export_all). -include("tftest.hrl"). %% Way to invoke just one test start([F]) -> ?line {ok, _} = ibrowse:start_link(), apply(app_test, F, []), ibrowse:stop(). start() -> io:format("~n ==== SRC_DIR TESTS ==== ~n~n", []), ?line {ok, _} = ibrowse:start_link(), test_srcdir_v1(), test_srcdir_v2(), test_srcdir_invalid(), ibrowse:stop(). %% ---- test_srcdir_v1() -> io:format("srcdir_v1~n",[]), Uri = "http://localhost:8000/srcdir_test", Res = "1.0", ?line {ok, "200", _, Content} = ibrowse:send_req(Uri, [], get), ?line Res = Content, ok. test_srcdir_v2() -> io:format("srcdir_v2~n",[]), Uri = "http://localhost:8000/srcdir_test", ?line ok = file:write_file(?builddir ++ "/include/srcdir_test.hrl", <<"-define(SRCDIR_VERSION, \"2.0\").">>), [_, Host] = string:tokens(atom_to_list(node()), "@"), Node = list_to_atom("test@" ++ Host), ?line Pid = rpc:call(Node, yaws, hup, [undefined]), ?line Ref = monitor(process, Pid), receive {'DOWN', Ref, process, Pid, _} -> ok after 10000 -> ?line throw(timeout) end, Res = "2.0", ?line {ok, "200", _, Content} = ibrowse:send_req(Uri, [], get), ?line Res = Content, ok. test_srcdir_invalid() -> io:format("srcdir_invalid~n",[]), Uri = "http://localhost:8000/srcdir_test", ?line ok = file:write_file(?builddir ++ "/include/srcdir_test.hrl", <<"invalid_header">>), [_, Host] = string:tokens(atom_to_list(node()), "@"), Node = list_to_atom("test@" ++ Host), ?line Pid = rpc:call(Node, yaws, hup, [undefined]), ?line Ref = monitor(process, Pid), receive {'DOWN', Ref, process, Pid, _} -> ok after 10000 -> ?line throw(timeout) end, Res = "2.0", ?line {ok, "200", _, Content} = ibrowse:send_req(Uri, [], get), ?line Res = Content, ok. yaws-2.0.2/test/t11/src/0000775000175000017500000000000012605311413011650 500000000000000yaws-2.0.2/test/t11/src/srcdir_test.erl0000664000175000017500000000025212605311413014620 00000000000000-module(srcdir_test). -export([out/1]). -include("srcdir_test.hrl"). out(_Arg) -> Content = ?SRCDIR_VERSION, [{status, 200}, {content, "text/plain", Content}]. yaws-2.0.2/test/t11/yaws.conf.in0000664000175000017500000000110412605311413013234 00000000000000logdir = @abs_builddir@/logs src_dir = @abs_srcdir@/src include_dir = @abs_builddir@/include trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 port = 8000 listen = 0.0.0.0 deflate = true docroot = @abs_builddir@/docroot-test appmods = srcdir_test yaws-2.0.2/test/t11/Makefile.am0000664000175000017500000000126212605311413013036 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl EXTRA_DIST = $(MODULES) src EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test prepare-test:: $(AM_V_at)$(INSTALL) -d include $(AM_V_at)echo "-define(SRCDIR_VERSION, \"1.0\")." > include/srcdir_test.hrl clean-test:: $(AM_V_at)rm -fr include distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/README0000664000175000017500000000033712605311413011257 00000000000000 To run all tests, do # make check at the toplevel, i.e. here To run tests in one of the test directories, go down there and do: # make test To run a specific test in e.g t2, do # cd t2 # make test TEST=test_name yaws-2.0.2/test/t3/0000775000175000017500000000000012605312015011001 500000000000000yaws-2.0.2/test/t3/Makefile.in0000664000175000017500000003627412605311446013011 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t3 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl \ authmodtest.erl \ outmodtest.erl \ rewritetest.erl EXTRA_DIST = $(MODULES) www1 www2 EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t3/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t3/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t3/www2/0000775000175000017500000000000012605311413011710 500000000000000yaws-2.0.2/test/t3/www2/test1/0000775000175000017500000000000012605311413012750 500000000000000yaws-2.0.2/test/t3/www2/test1/a.txt0000664000175000017500000000000012605311413013637 00000000000000yaws-2.0.2/test/t3/www2/test2/0000775000175000017500000000000012605311413012751 500000000000000yaws-2.0.2/test/t3/www2/test2/b.txt0000664000175000017500000000000012605311413013641 00000000000000yaws-2.0.2/test/t3/www1/0000775000175000017500000000000012605311413011707 500000000000000yaws-2.0.2/test/t3/www1/test3/0000775000175000017500000000000012605311413012751 500000000000000yaws-2.0.2/test/t3/www1/test3/sub/0000775000175000017500000000000012605311413013542 500000000000000yaws-2.0.2/test/t3/www1/test3/sub/a.txt0000664000175000017500000000000012605311413014431 00000000000000yaws-2.0.2/test/t3/www1/test6/0000775000175000017500000000000012605311413012754 500000000000000yaws-2.0.2/test/t3/www1/test6/a.txt0000664000175000017500000000000012605311413013643 00000000000000yaws-2.0.2/test/t3/www1/test8/0000775000175000017500000000000012605311413012756 500000000000000yaws-2.0.2/test/t3/www1/test8/b.txt0000664000175000017500000000000012605311413013646 00000000000000yaws-2.0.2/test/t3/www1/test8/a.txt0000664000175000017500000000000012605311413013645 00000000000000yaws-2.0.2/test/t3/www1/test9/0000775000175000017500000000000012605311413012757 500000000000000yaws-2.0.2/test/t3/www1/test9/a.txt0000664000175000017500000000000012605311413013646 00000000000000yaws-2.0.2/test/t3/www1/test4/0000775000175000017500000000000012605311413012752 500000000000000yaws-2.0.2/test/t3/www1/test4/a.txt0000664000175000017500000000000012605311413013641 00000000000000yaws-2.0.2/test/t3/www1/test7/0000775000175000017500000000000012605311413012755 500000000000000yaws-2.0.2/test/t3/www1/test7/b.txt0000664000175000017500000000000012605311413013645 00000000000000yaws-2.0.2/test/t3/www1/test7/a.txt0000664000175000017500000000000012605311413013644 00000000000000yaws-2.0.2/test/t3/www1/test10/0000775000175000017500000000000012605311413013027 500000000000000yaws-2.0.2/test/t3/www1/test10/b.txt0000664000175000017500000000000012605311413013717 00000000000000yaws-2.0.2/test/t3/www1/test10/.yaws_auth0000664000175000017500000000016512605311413014756 00000000000000%% only check authorization for a.txt and b.txt {realm, "test10"}. {file, "a.txt"}. {file, "b.txt"}. {"foo", "bar"}. yaws-2.0.2/test/t3/www1/test10/a.txt0000664000175000017500000000000012605311413013716 00000000000000yaws-2.0.2/test/t3/www1/test10/c.txt0000664000175000017500000000000012605311413013720 00000000000000yaws-2.0.2/test/t3/www1/test2/0000775000175000017500000000000012605311413012750 500000000000000yaws-2.0.2/test/t3/www1/test2/a.txt0000664000175000017500000000000012605311413013637 00000000000000yaws-2.0.2/test/t3/www1/test5/0000775000175000017500000000000012605311413012753 500000000000000yaws-2.0.2/test/t3/www1/test5/a.txt0000664000175000017500000000000012605311413013642 00000000000000yaws-2.0.2/test/t3/app_test.erl0000664000175000017500000001312412605311413013246 00000000000000-module(app_test). -compile(export_all). -include_lib("ibrowse/include/ibrowse.hrl"). -include("tftest.hrl"). %% Way to invoke just one test start([F]) -> ?line {ok, _} = ibrowse:start_link(), apply(app_test, F, []), ibrowse:stop(). start() -> io:format("\n ==== AUTH TESTS ==== \n\n", []), ?line {ok, _} = ibrowse:start_link(), test1(), test2(), test3(), test4(), test5(), test6(), test7(), test8(), test9(), test10(), test11(), ibrowse:stop(). test1() -> io:format("test1\n", []), Uri = "http://localhost:8000/test1/a.txt", ?line {ok, "401", Hdrs, _} = ibrowse:send_req(Uri, [], get), ?line "Basic realm=\"test1\"" = proplists:get_value("WWW-Authenticate", Hdrs), Opts1 = [{basic_auth, {"foo", "baz"}}], ?line {ok, "401", _, _} = ibrowse:send_req(Uri, [], get, [], Opts1), Opts2 = [{basic_auth, {"foo", "bar"}}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, [], get, [], Opts2), ok. test2() -> io:format("test2\n", []), Uri1 = "http://localhost:8000/test2/a.txt", ?line {ok, "401", Hdrs, _} = ibrowse:send_req(Uri1, [], get), ?line "Basic realm=\"test2\"" = proplists:get_value("WWW-Authenticate", Hdrs), Uri2 = "http://localhost:8000/test2/b.txt", ?line {ok, "200", _, _} = ibrowse:send_req(Uri2, [], get), ok. test3() -> io:format("test3\n", []), Uri = "http://localhost:8000/test3/sub/a.txt", ?line {ok, "401", Hdrs, _} = ibrowse:send_req(Uri, [], get), ?line "Basic realm=\"test3\"" = proplists:get_value("WWW-Authenticate", Hdrs), Opts2 = [{basic_auth, {"foo", "bar"}}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, [], get, [], Opts2), ok. test4() -> io:format("test4\n", []), Uri = "http://localhost:8000/test4/a.txt", ?line {ok, "401", Hdrs, _} = ibrowse:send_req(Uri, [], get), ?line "Basic realm=\"test4\"" = proplists:get_value("WWW-Authenticate", Hdrs), Opts = [{basic_auth, {"foo", "bar"}}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, [], get, [], Opts), ok. test5() -> io:format("test5\n", []), Uri = "http://localhost:8000/test5/a.txt", ?line {ok, "200", Hdrs, "test5"} = ibrowse:send_req(Uri, [], get), ?line "true" = proplists:get_value("X-Outmod-Test", Hdrs), ?line "Basic realm=\"test5\"" = proplists:get_value("WWW-Authenticate", Hdrs), ok. test6() -> io:format("test6\n", []), Uri = "http://localhost:8000/test6/a.txt", ?line {ok, "200", _, _} = ibrowse:send_req(Uri, [], get), ok. test7() -> io:format("test7\n", []), Uri1 = "http://localhost:8000/test7/a.txt", ?line {ok, "403", _, _} = ibrowse:send_req(Uri1, [], get), Uri2 = "http://localhost:8000/test7/b.txt", ?line {ok, "200", _, _} = ibrowse:send_req(Uri2, [], get), ok. test8() -> io:format("test8\n", []), Uri1 = "http://localhost:8000/test8/a.txt", ?line {ok, "403", _, _} = ibrowse:send_req(Uri1, [], get), Uri2 = "http://localhost:8000/test8/b.txt", ?line {ok, "200", _, _} = ibrowse:send_req(Uri2, [], get), ok. test9() -> io:format("test9\n", []), Uri = "http://localhost:8000/test9/a.txt", Opts = [{basic_auth, {"foo", "baz"}}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, [], get, [], Opts), ok. test10() -> io:format("test10\n", []), Opts = [{basic_auth, {"foo", "bar"}}], Uri1 = "http://localhost:8000/test10/a.txt", ?line {ok, "401", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), ?line "Basic realm=\"test10\"" = proplists:get_value("WWW-Authenticate", Hdrs1), ?line {ok, "200", _, _} = ibrowse:send_req(Uri1, [], get, [], Opts), Uri2 = "http://localhost:8000/test10/b.txt", ?line {ok, "401", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line "Basic realm=\"test10\"" = proplists:get_value("WWW-Authenticate", Hdrs2), ?line {ok, "200", _, _} = ibrowse:send_req(Uri2, [], get, [], Opts), Uri3 = "http://localhost:8000/test10/c.txt", ?line {ok, "200", _, _} = ibrowse:send_req(Uri3, [], get), ok. test11() -> io:format("test11\n", []), Opts1 = [{basic_auth, {"foo", "bar"}}], Opts2 = [{basic_auth, {"foo", "baz"}}], Uri1 = "http://localhost:8000/test11_1/a.txt", ?line {ok, "401", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), ?line "Basic realm=\"test1\"" = proplists:get_value("WWW-Authenticate", Hdrs1), ?line {ok, "200", _, _} = ibrowse:send_req(Uri1, [], get, [], Opts1), Uri2 = "http://localhost:8000/test11_2/a.txt", ?line {ok, "401", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line "Basic realm=\"test11_2\"" = proplists:get_value("WWW-Authenticate", Hdrs2), ?line {ok, "200", _, _} = ibrowse:send_req(Uri2, [], get, [], Opts1), Uri3 = "http://localhost:8000/test11_3/a.txt", ?line {ok, "401", Hdrs3_1, _} = ibrowse:send_req(Uri3, [], get), ?line "Basic realm=\"test11_3\"" = proplists:get_value("WWW-Authenticate", Hdrs3_1), ?line {ok, "401", Hdrs3_2, _} = ibrowse:send_req(Uri3, [], get, [], Opts1), ?line "Basic realm=\"test11_3\"" = proplists:get_value("WWW-Authenticate", Hdrs3_2), ?line {ok, "401", Hdrs3_3, _} = ibrowse:send_req(Uri3, [], get, [], Opts2), ?line "Basic realm=\"test1\"" = proplists:get_value("WWW-Authenticate", Hdrs3_3), Uri4 = "http://localhost:8000/test11_4/a.txt", ?line {ok, "403", _, _} = ibrowse:send_req(Uri4, [], get), Uri5 = "http://localhost:8000/test11_4/b.txt", ?line {ok, "401", Hdrs5, _} = ibrowse:send_req(Uri5, [], get), ?line "Basic realm=\"test11_4\"" = proplists:get_value("WWW-Authenticate", Hdrs5), ?line {ok, "200", _, _} = ibrowse:send_req(Uri5, [], get, [], Opts1), ok. yaws-2.0.2/test/t3/outmodtest.erl0000664000175000017500000000045712605311413013643 00000000000000-module(outmodtest). -export([auth/2, out401/3]). -include("../../include/yaws.hrl"). -include("../../include/yaws_api.hrl"). auth(#arg{}, #auth{}) -> {appmod, ?MODULE}. out401(#arg{}, #auth{}, Realm) -> [{status, 200}, {header, "X-Outmod-Test: true"}, {content, "text/plain", Realm}]. yaws-2.0.2/test/t3/authmodtest.erl0000664000175000017500000000045112605311413013767 00000000000000-module(authmodtest). -export([auth/2]). -include("../../include/yaws.hrl"). -include("../../include/yaws_api.hrl"). auth(#arg{}=Arg, #auth{}) -> H = Arg#arg.headers, case H#headers.authorization of {"foo", "bar", _} -> true; _ -> false end. yaws-2.0.2/test/t3/rewritetest.erl0000664000175000017500000000156312605311413014014 00000000000000-module(rewritetest). -export([arg_rewrite/1]). -include("../../include/yaws_api.hrl"). arg_rewrite(Arg) -> Url = yaws_api:request_url(Arg), case Url#url.path of "/test11_1/" ++ Rest -> Req0 = Arg#arg.req, Req1 = Req0#http_request{path={abs_path,"/test1/" ++ Rest}}, Arg#arg{req=Req1}; "/test11_2/" ++ Rest -> Req0 = Arg#arg.req, Req1 = Req0#http_request{path={abs_path,"/test1/" ++ Rest}}, Arg#arg{req=Req1}; "/test11_3/" ++ Rest -> Req0 = Arg#arg.req, Req1 = Req0#http_request{path={abs_path,"/test1/" ++ Rest}}, Arg#arg{req=Req1}; "/test11_4/" ++ Rest -> Req0 = Arg#arg.req, Req1 = Req0#http_request{path={abs_path,"/test7/" ++ Rest}}, Arg#arg{req=Req1}; _ -> Arg end. yaws-2.0.2/test/t3/yaws.conf.in0000664000175000017500000001076312605311413013170 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 port = 8000 listen = 0.0.0.0 deflate = true docroot = @abs_srcdir@/www1 @abs_srcdir@/www2 arg_rewrite_mod = rewritetest # Auth needed to access to test1 in www2, realm = test1 dir = /test1 user = foo:bar # Auth needed to access to test2/a.txt in www1, # but not for test2/b.txt in www2, docroot = @abs_srcdir@/www1 realm = test2 dir = /test2 user = foo:bar # Auth needed to access to test3 in www1, # and all subdirs realm = test3 dir = /test3 user = foo:bar # Use authmod to authenticate users realm = test4 dir = /test4 authmod = authmodtest # Use authmod to authenticate users, # it will set the outmod to handle 401 output realm = test5 dir = /test5 authmod = outmodtest # because of order value, 127.0.0.1 is authorized realm = test6 dir = /test6 deny = all allow = 127.0.0.1 order = deny,allow # because of order value, 127.0.0.1 is denied realm = test7_1 dir = /test7 deny = all allow = 127.0.0.1 order = allow,deny # Override previous test to authorized 127.0.0.1 # (deny target was removed) realm = test7_2 dir = /test7/b.txt allow = 127.0.0.1 order = allow,deny # because of order value, all ips are denied # (no allow or deny target) realm = test8_1 dir = /test8/a.txt order = allow,deny # because of order value, all ips are authorized # (no allow or deny target) realm = test8_2 dir = /test8/b.txt order = deny,allow # Use many auth method: authmod + basic auth + acls # authorized is Ip=127.0.0.1 and user:pass == foo:baz realm = test9 dir = /test9 authmod = authmodtest # return false is user:pass != foo:bar user = foo:baz deny = all allow = 127.0.0.1 order = deny,allow # /test11_1 is redirected to /test1. There is no check for /test11_1, so # only those on /test1 are applied. # /test11_2 is redirected to /test1. So check /test11_2 and /test1: # - Only user foo:bar can access to /test11_2 # - Only user foo:bar can access to /test1 # # => Requests to /test11_2 are always accepted for user foo:bar and # denied for everybody else. realm = test11_2 dir = /test11_2 user = foo:bar # /test11_3 is redirected to /test1. So check /test11_3 and /test1: # - Only user foo:baz can access to /test11_3 # - Only user foo:bar can access to /test1 # # => Requests to /test11_3 are always rejected # (same user, different password) realm = test11_3 dir = /test11_3 user = foo:baz # /test11_4 is redirected to /test7. So check /test11_4 and /test7: # - Only user foo:bar can access to /test11_4 # - /test7/a.txt is forbidden for 127.0.0.1 # - /test7/b.txt is authorized for 127.0.0.1 # # => Requests to /test11_4/a.txt coming from 127.0.0.1 are rejected # => Requests to /test11_4/b.txt coming from 127.0.0.1 are accepted # for user foo:bar only realm = test11_4 dir = /test11_4 user = foo:bar yaws-2.0.2/test/t3/Makefile.am0000664000175000017500000000112012605311413012750 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl \ authmodtest.erl \ outmodtest.erl \ rewritetest.erl EXTRA_DIST = $(MODULES) www1 www2 EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/t6/0000775000175000017500000000000012605312015011004 500000000000000yaws-2.0.2/test/t6/Makefile.in0000664000175000017500000004030512605311446013002 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t6 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/no_docroot_appmod.conf.in \ $(srcdir)/no_docroot_fwdproxy.conf.in \ $(srcdir)/no_docroot_redirect.conf.in \ $(srcdir)/no_docroot_revproxy.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = no_docroot_appmod.conf no_docroot_fwdproxy.conf \ no_docroot_redirect.conf no_docroot_revproxy.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ NO_DOCROOT_TESTS = no_docroot_revproxy \ no_docroot_fwdproxy \ no_docroot_redirect \ no_docroot_appmod gen_rule = $1: YAWS_CONF=$1.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t6/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t6/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): no_docroot_appmod.conf: $(top_builddir)/config.status $(srcdir)/no_docroot_appmod.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ no_docroot_fwdproxy.conf: $(top_builddir)/config.status $(srcdir)/no_docroot_fwdproxy.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ no_docroot_redirect.conf: $(top_builddir)/config.status $(srcdir)/no_docroot_redirect.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ no_docroot_revproxy.conf: $(top_builddir)/config.status $(srcdir)/no_docroot_revproxy.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test check-local: log $(NO_DOCROOT_TESTS) log: @echo @echo " ==== NO DOCROOT TESTS ==== " @echo $(foreach r,$(NO_DOCROOT_TESTS), $(eval $(call gen_rule,$r))) $(NO_DOCROOT_TESTS): $(top_builddir)/test/bin/yaws $(AM_V_at)$(INSTALL) -d logs $(AM_V_at)$(top_builddir)/test/bin/yaws -sname test --daemon --id testid --conf $(YAWS_CONF) $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --wait-started=$(WAIT_TIME) @echo $@ $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --stop >/dev/null $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --wait-stopped=$(WAIT_TIME) distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t6/no_docroot_appmod.conf.in0000664000175000017500000000074512605311413015714 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 listen = 0.0.0.0 port = 8000 appmods = <"/", app_module> yaws-2.0.2/test/t6/no_docroot_revproxy.conf.in0000664000175000017500000000075312605311413016331 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 listen = 0.0.0.0 port = 8000 revproxy = "/" http://yaws.hyber.org yaws-2.0.2/test/t6/no_docroot_fwdproxy.conf.in0000664000175000017500000000072612605311413016315 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 listen = 0.0.0.0 port = 8000 fwdproxy = true yaws-2.0.2/test/t6/no_docroot_redirect.conf.in0000664000175000017500000000100712605311413016225 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 listen = 0.0.0.0 port = 8000 "/" == http://yaws.hyber.org/ yaws-2.0.2/test/t6/Makefile.am0000664000175000017500000000161212605311413012761 00000000000000NO_DOCROOT_TESTS = no_docroot_revproxy \ no_docroot_fwdproxy \ no_docroot_redirect \ no_docroot_appmod include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test check-local: log $(NO_DOCROOT_TESTS) log: @echo @echo " ==== NO DOCROOT TESTS ==== " @echo gen_rule = $1: YAWS_CONF=$1.conf $(foreach r,$(NO_DOCROOT_TESTS), $(eval $(call gen_rule,$r))) $(NO_DOCROOT_TESTS): $(top_builddir)/test/bin/yaws $(AM_V_at)$(INSTALL) -d logs $(AM_V_at)$(top_builddir)/test/bin/yaws -sname test --daemon --id testid --conf $(YAWS_CONF) $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --wait-started=$(WAIT_TIME) @echo $@ $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --stop >/dev/null $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --wait-stopped=$(WAIT_TIME) distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/t10/0000775000175000017500000000000012605312015011057 500000000000000yaws-2.0.2/test/t10/Makefile.in0000664000175000017500000003616512605311446013066 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t10 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl EXTRA_DIST = $(MODULES) EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t10/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t10/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t10/app_test.erl0000664000175000017500000021546412605311413013337 00000000000000-module(app_test). -compile(export_all). -include("tftest.hrl"). -record(frame, {fin = true, rsv = 0, opcode, masked = false, mask, payload = <<>>}). -define(WS_OPCODE_CONTINUATION, 16#00). -define(WS_OPCODE_TEXT, 16#01). -define(WS_OPCODE_BINARY, 16#02). -define(WS_OPCODE_CLOSE, 16#08). -define(WS_OPCODE_PING, 16#09). -define(WS_OPCODE_PONG, 16#0A). -define(WS_STATUS_NORMAL, 1000). -define(WS_STATUS_PROTO_ERROR, 1002). -define(WS_STATUS_ABNORMAL_CLOSURE, 1006). -define(WS_STATUS_INVALID_PAYLOAD, 1007). -define(WS_STATUS_MSG_TOO_BIG, 1009). -define(WS_STATUS_INTERNAL_ERROR, 1011). -ifdef(HAVE_CRYPTO_HASH). -define(CRYPTO_HASH(V), crypto:hash(sha,V)). -else. -define(CRYPTO_HASH(V), crypto:sha(V)). -endif. %% Way to invoke just one test start([F]) -> apply(app_test, F, []), ok. start() -> io:format("~n ==== WEBSOCKET TESTS ==== ~n~n", []), test_valid_opening_handshake(), test_bad_version_handshake(), test_bad_origin_handshake(), test_noconnection_handshake(), test_bad_connection_handshake(), test_noupgrade_handshake(), test_bad_upgrade_handshake(), test_basic_unfragmented_text(0, all), test_basic_unfragmented_text(125, all), test_basic_unfragmented_text(126, all), test_basic_unfragmented_text(127, all), test_basic_unfragmented_text(128, all), test_basic_unfragmented_text(65535, all), test_basic_unfragmented_text(65536, all), test_basic_unfragmented_text(65536, 997), test_advanced_unfragmented_text(0, all), test_advanced_unfragmented_text(125, all), test_advanced_unfragmented_text(126, all), test_advanced_unfragmented_text(127, all), test_advanced_unfragmented_text(128, all), test_advanced_unfragmented_text(65535, all), test_advanced_unfragmented_text(65536, all), test_advanced_unfragmented_text(65536, 997), test_basic_unfragmented_binary(0, all), test_basic_unfragmented_binary(125, all), test_basic_unfragmented_binary(126, all), test_basic_unfragmented_binary(127, all), test_basic_unfragmented_binary(128, all), test_basic_unfragmented_binary(65535, all), test_basic_unfragmented_binary(65536, all), test_basic_unfragmented_binary(65536, 997), test_advanced_unfragmented_binary(0, all), test_advanced_unfragmented_binary(125, all), test_advanced_unfragmented_binary(126, all), test_advanced_unfragmented_binary(127, all), test_advanced_unfragmented_binary(128, all), test_advanced_unfragmented_binary(65535, all), test_advanced_unfragmented_binary(65536, all), test_advanced_unfragmented_binary(65536, 997), test_basic_ping_text(0, all), test_basic_ping_text(125, all), test_basic_ping_binary(125, all), test_basic_ping_binary(125, 1), test_advanced_ping_text(0, all), test_advanced_ping_text(125, all), test_advanced_ping_binary(125, all), test_advanced_ping_binary(125, 1), test_toolong_payload_ping(), test_basic_unsolicited_pong(0), test_basic_unsolicited_pong(125), test_advanced_unsolicited_pong(0), test_advanced_unsolicited_pong(125), test_basic_unsolicited_pong_ping_pong(), test_advanced_unsolicited_pong_ping_pong(), test_basic_10_pings(all), test_basic_10_pings(1), test_advanced_10_pings(all), test_advanced_10_pings(1), test_badrsv_text(), test_badrsv_binary(), test_badrsv_ping(), test_badrsv_close(), test_badrsv_complex(all), test_badrsv_complex(1), test_badopcodes(), test_basic_fragmented_empty(), test_basic_fragmented_text_1(), test_basic_fragmented_binary_1(), test_basic_fragmented_text_2(), test_basic_fragmented_binary_2(), test_basic_fragmented_ping(), test_basic_fragmented_pong(), test_basic_fragmented_close(), test_basic_fragmented_text_with_ping(), test_basic_fragmented_text_with_pong(), test_basic_badfragmented_1(), test_basic_badfragmented_2(), test_basic_badfragmented_nocontinuation(), test_advanced_fragmented_empty(), test_advanced_fragmented_text_1(), test_advanced_fragmented_binary_1(), test_advanced_fragmented_text_2(), test_advanced_fragmented_binary_2(), test_advanced_fragmented_ping(), test_advanced_fragmented_pong(), test_advanced_fragmented_close(), test_advanced_fragmented_text_with_ping(), test_advanced_fragmented_text_with_pong(), test_advanced_badfragmented_1(), test_advanced_badfragmented_2(), test_basic_badfragmented_nocontinuation(), test_basic_unfragmented_valid_utf8_text(all), test_basic_unfragmented_valid_utf8_text(1), test_basic_fragmented_valid_utf8_text(all), test_basic_fragmented_valid_utf8_text(1), test_advanced_unfragmented_valid_utf8_text(all), test_advanced_unfragmented_valid_utf8_text(1), test_advanced_fragmented_valid_utf8_text(all), test_advanced_fragmented_valid_utf8_text(1), test_basic_unfragmented_invalid_utf8_text(all), test_basic_unfragmented_invalid_utf8_text(1), test_basic_fragmented_invalid_utf8_text(all), test_basic_fragmented_invalid_utf8_text(1), test_advanced_unfragmented_invalid_utf8_text(all), test_advanced_unfragmented_invalid_utf8_text(1), test_advanced_fragmented_invalid_utf8_text(all), test_advanced_fragmented_invalid_utf8_text(1), test_basic_2_closes(), test_basic_close_ping(), test_basic_close_text(), test_basic_fragtext_close_fragtext(), test_basic_close_empty(), test_basic_close_toosmall(), test_basic_close_statusonly(), test_basic_close_with_reason(), test_basic_close_limit_size(), test_basic_close_toolong(), test_basic_close_invalid_utf8(), test_basic_close_valid_codes(), test_basic_close_invalid_codes(), test_advanced_2_closes(), test_advanced_close_ping(), test_advanced_close_text(), test_advanced_fragtext_close_fragtext(), test_advanced_close_empty(), test_advanced_close_toosmall(), test_advanced_close_statusonly(), test_advanced_close_with_reason(), test_advanced_close_limit_size(), test_advanced_close_toolong(), test_advanced_close_invalid_utf8(), test_advanced_close_valid_codes(), test_advanced_close_invalid_codes(), test_close_timeout(), test_keepalive_timeout(), test_too_big_frame(), test_too_big_message(), test_close_unmasked_frame(), test_secure_websocket(), ok. %% ---- test_valid_opening_handshake() -> io:format("valid_opening_handshake~n",[]), WSPath = "/websockets_example_endpoint.yaws", Key = "dGhlIHNhbXBsZSBub25jZQ==", %% Send the handshake and retrieve the response ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, Hds}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), %% Check the server response ?line true = is_valid_handshake_hash( Key, proplists:get_value("sec-websocket-accept", Hds) ), ?line "websocket" = string:to_lower(proplists:get_value("upgrade", Hds)), ?line "upgrade" = string:to_lower(proplists:get_value("connection", Hds)), %% Close the webscoket and check the server reply ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_bad_version_handshake() -> io:format("bad_version_handshake~n",[]), WSPath = "/websockets_example_endpoint.yaws", Key = "dGhlIHNhbXBsZSBub25jZQ==", %% Send the handshake and retrieve the response ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {400, Hds}} = wsopen(Sock, Key, WSPath, "http://localhost", 15), %% Check the server response ?line "13, 8" = string:to_lower( proplists:get_value("sec-websocket-version", Hds) ), ?line ok = close(Sock), ok. %% ---- test_bad_origin_handshake() -> io:format("bad_origin_handshake~n",[]), WSPath = "/websockets_example_endpoint.yaws", Key = "dGhlIHNhbXBsZSBub25jZQ==", %% Send the handshake and retrieve the response ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {403, _}} = wsopen(Sock, Key, WSPath, "http://otherhost", 13), ?line ok = close(Sock), ok. %% ---- test_noconnection_handshake() -> io:format("noconnection_handshake~n",[]), WSPath = "/websockets_example_endpoint.yaws", Key = "dGhlIHNhbXBsZSBub25jZQ==", %% Send the handshake and retrieve the response ?line {ok, Sock} = open("localhost", 8000), Handshake = ["GET ", WSPath, " HTTP/1.1\r\n", "Host: localhost\r\n", "Upgrade: websocket\r\n", "Sec-WebSocket-Key: ", Key, "\r\n", "Origin: http://localhost\r\n", "Sec-WebSocket-Version: 13\r\n", "\r\n"], case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:send(SslSock, Handshake); undefined -> gen_tcp:send(Sock, Handshake) end, ?line {ok, {400, _}} = read_handshake_response(Sock), ?line ok = close(Sock), ok. %% ---- test_bad_connection_handshake() -> io:format("bad_connection_handshake~n",[]), WSPath = "/websockets_example_endpoint.yaws", Key = "dGhlIHNhbXBsZSBub25jZQ==", %% Send the handshake and retrieve the response ?line {ok, Sock} = open("localhost", 8000), Handshake = ["GET ", WSPath, " HTTP/1.1\r\n", "Host: localhost\r\n", "Upgrade: websocket\r\n", "Connection: Keep-Alive\r\n", "Sec-WebSocket-Key: ", Key, "\r\n", "Origin: http://localhost\r\n", "Sec-WebSocket-Version: 13\r\n", "\r\n"], case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:send(SslSock, Handshake); undefined -> gen_tcp:send(Sock, Handshake) end, ?line {ok, {400, _}} = read_handshake_response(Sock), ?line ok = close(Sock), ok. %% ---- test_noupgrade_handshake() -> io:format("noupgrade_handshake~n",[]), WSPath = "/websockets_example_endpoint.yaws", Key = "dGhlIHNhbXBsZSBub25jZQ==", %% Send the handshake and retrieve the response ?line {ok, Sock} = open("localhost", 8000), Handshake = ["GET ", WSPath, " HTTP/1.1\r\n", "Host: localhost\r\n", "Connection: Upgrade\r\n", "Sec-WebSocket-Key: ", Key, "\r\n", "Origin: http://localhost\r\n", "Sec-WebSocket-Version: 13\r\n", "\r\n"], case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:send(SslSock, Handshake); undefined -> gen_tcp:send(Sock, Handshake) end, ?line {ok, {400, _}} = read_handshake_response(Sock), ?line ok = close(Sock), ok. %% ---- test_bad_upgrade_handshake() -> io:format("bad_upgrade_handshake~n",[]), WSPath = "/websockets_example_endpoint.yaws", Key = "dGhlIHNhbXBsZSBub25jZQ==", %% Send the handshake and retrieve the response ?line {ok, Sock} = open("localhost", 8000), Handshake = ["GET ", WSPath, " HTTP/1.1\r\n", "Host: localhost\r\n", "Upgrade: TLS/1.0\r\n", "Connection: Upgrade\r\n", "Sec-WebSocket-Key: ", Key, "\r\n", "Origin: http://localhost\r\n", "Sec-WebSocket-Version: 13\r\n", "\r\n"], case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:send(SslSock, Handshake); undefined -> gen_tcp:send(Sock, Handshake) end, ?line {ok, {400, _}} = read_handshake_response(Sock), ?line ok = close(Sock), ok. %% ---- test_basic_unfragmented_text(Sz, BlockSz) -> io:format("basic_unfragmented_text (len=~p, blocksize=~p)~n", [Sz, BlockSz]), Payload = list_to_binary(lists:duplicate(Sz, $*)), do_test_unfragmented_msg("/websockets_example_endpoint.yaws", ?WS_OPCODE_TEXT, Payload, BlockSz). test_advanced_unfragmented_text(Sz, BlockSz) -> io:format("advanced_unfragmented_text (len=~p, blocksize=~p)~n", [Sz, BlockSz]), Payload = list_to_binary(lists:duplicate(Sz, $*)), do_test_unfragmented_msg("/websockets_autobahn_endpoint.yaws", ?WS_OPCODE_TEXT, Payload, BlockSz). test_basic_unfragmented_binary(Sz, BlockSz) -> io:format("basic_unfragmented_binary (len=~p, blocksize=~p)~n", [Sz, BlockSz]), Payload = list_to_binary(lists:duplicate(Sz, 16#fe)), do_test_unfragmented_msg("/websockets_example_endpoint.yaws", ?WS_OPCODE_BINARY, Payload, BlockSz). test_advanced_unfragmented_binary(Sz, BlockSz) -> io:format("advanced_unfragmented_binary (len=~p, blocksize=~p)~n", [Sz, BlockSz]), Payload = list_to_binary(lists:duplicate(Sz, 16#fe)), do_test_unfragmented_msg("/websockets_autobahn_endpoint.yaws", ?WS_OPCODE_BINARY, Payload, BlockSz). do_test_unfragmented_msg(WSPath, Type, Payload, BlockSz) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), %% unmasked SndFrame1 = #frame{opcode=Type, payload=Payload}, ?line ok = send_frame(Sock, SndFrame1, BlockSz), ?line {ok, RcvFrame1} = read_frame(Sock), ?line Type = RcvFrame1#frame.opcode, ?line Payload = RcvFrame1#frame.payload, %% masked SndFrame2 = SndFrame1#frame{masked=true, mask = <<"abcd">>}, ?line ok = send_frame(Sock, SndFrame2, BlockSz), ?line {ok, RcvFrame2} = read_frame(Sock), ?line Type = RcvFrame2#frame.opcode, ?line Payload = RcvFrame2#frame.payload, ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% --- test_basic_ping_text(Sz, BlockSz) -> io:format("basic_ping_text (len=~p, blocksize=~p)~n", [Sz, BlockSz]), Payload = list_to_binary(lists:duplicate(Sz, $*)), do_test_ping_msg("/websockets_example_endpoint.yaws", Payload, BlockSz). test_advanced_ping_text(Sz, BlockSz) -> io:format("advanced_ping_text (len=~p, blocksize=~p)~n", [Sz, BlockSz]), Payload = list_to_binary(lists:duplicate(Sz, $*)), do_test_ping_msg("/websockets_autobahn_endpoint.yaws", Payload, BlockSz). test_basic_ping_binary(Sz, BlockSz) -> io:format("basic_ping_binary (len=~p, blocksize=~p)~n", [Sz, BlockSz]), Payload = list_to_binary(lists:duplicate(Sz, 16#fe)), do_test_ping_msg("/websockets_example_endpoint.yaws", Payload, BlockSz). test_advanced_ping_binary(Sz, BlockSz) -> io:format("advanced_ping_binary (len=~p, blocksize=~p)~n", [Sz, BlockSz]), Payload = list_to_binary(lists:duplicate(Sz, 16#fe)), do_test_ping_msg("/websockets_autobahn_endpoint.yaws", Payload, BlockSz). do_test_ping_msg(WSPath, Payload, BlockSz) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), %% unmasked SndFrame1 = #frame{opcode=?WS_OPCODE_PING, payload=Payload}, ?line ok = send_frame(Sock, SndFrame1, BlockSz), ?line {ok, RcvFrame1} = read_frame(Sock), ?line ?WS_OPCODE_PONG = RcvFrame1#frame.opcode, ?line Payload = RcvFrame1#frame.payload, %% masked SndFrame2 = SndFrame1#frame{masked=true, mask = <<"abcd">>}, ?line ok = send_frame(Sock, SndFrame2, BlockSz), ?line {ok, RcvFrame2} = read_frame(Sock), ?line ?WS_OPCODE_PONG = RcvFrame2#frame.opcode, ?line Payload = RcvFrame2#frame.payload, ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_toolong_payload_ping() -> io:format("toolong_payload_ping ~n", []), WSPath = "/websockets_example_endpoint.yaws", Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload = list_to_binary(lists:duplicate(126, 16#fe)), ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame = #frame{opcode=?WS_OPCODE_PING, payload=Payload}, ?line ok = send_frame(Sock, SndFrame, all), ?line {ok, Frames} = wsflush(Sock, false), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line {ok, []} = wsflush(Sock, true), ?line ok = close(Sock), ok. %% ---- test_basic_unsolicited_pong(Sz) -> io:format("basic_unsolicited_pong (len=~p)~n", [Sz]), Payload = list_to_binary(lists:duplicate(Sz, 16#fe)), do_test_unsolicited_pong_msg("/websockets_example_endpoint.yaws", Payload). test_advanced_unsolicited_pong(Sz) -> io:format("advanced_unsolicited_pong (len=~p)~n", [Sz]), Payload = list_to_binary(lists:duplicate(Sz, 16#fe)), do_test_unsolicited_pong_msg("/websockets_autobahn_endpoint.yaws", Payload). do_test_unsolicited_pong_msg(WSPath, Payload) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame = #frame{opcode=?WS_OPCODE_PONG, payload=Payload}, ?line ok = send_frame(Sock, SndFrame, all), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_unsolicited_pong_ping_pong() -> io:format("basic_unsolicited_pong_ping_pong~n", []), do_test_unsolicited_pong_ping_pong("/websockets_example_endpoint.yaws"). test_advanced_unsolicited_pong_ping_pong() -> io:format("advanced_unsolicited_pong_ping_pong~n", []), do_test_unsolicited_pong_ping_pong("/websockets_autobahn_endpoint.yaws"). do_test_unsolicited_pong_ping_pong(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload1 = list_to_binary(lists:duplicate(125, $*)), Payload2 = <<"ping payload">>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame1 = #frame{opcode=?WS_OPCODE_PONG, payload=Payload1}, ?line ok = send_frame(Sock, SndFrame1, all), SndFrame2 = #frame{opcode=?WS_OPCODE_PING, payload=Payload2}, ?line ok = send_frame(Sock, SndFrame2, all), ?line {ok, RcvFrame2} = read_frame(Sock), ?line ?WS_OPCODE_PONG = RcvFrame2#frame.opcode, ?line Payload2 = RcvFrame2#frame.payload, ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_10_pings(BlockSz) -> io:format("basic_10_pings (blocksize=~p)~n", [BlockSz]), do_test_10_pings("/websockets_example_endpoint.yaws", BlockSz). test_advanced_10_pings(BlockSz) -> io:format("advanced_10_pings (blocksize=~p)~n", [BlockSz]), do_test_10_pings("/websockets_autobahn_endpoint.yaws", BlockSz). do_test_10_pings(WSPath, BlockSz) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload = <<"ping payload">>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame = #frame{opcode=?WS_OPCODE_PING, payload=Payload}, ?line ok = apply_loop(10, fun send_frame/3, [Sock, SndFrame, BlockSz], ok), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, Frames} = wsflush(Sock, true), {Frames1, Frames2} = lists:split(10, Frames), ?line true = lists:all(fun(#frame{payload=P}) -> P == Payload end, Frames1), ?line true = is_valid_close_frame(Frames2, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_badrsv_text() -> io:format("badrsv_text (rsv=1)~n", []), do_test_badrsv("/websockets_example_endpoint.yaws", ?WS_OPCODE_TEXT, 1). test_badrsv_binary() -> io:format("badrsv_binary (rsv=2)~n", []), do_test_badrsv("/websockets_example_endpoint.yaws", ?WS_OPCODE_BINARY, 2). test_badrsv_ping() -> io:format("badrsv_ping (rsv=3)~n", []), do_test_badrsv("/websockets_example_endpoint.yaws", ?WS_OPCODE_PING, 3). test_badrsv_close() -> io:format("badrsv_close (rsv=4)~n", []), do_test_badrsv("/websockets_example_endpoint.yaws", ?WS_OPCODE_CLOSE, 4). do_test_badrsv(WSPath, Type, Rsv) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload = <<"small payload">>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame = #frame{rsv=Rsv, opcode=Type, payload=Payload}, ?line ok = send_frame(Sock, SndFrame, all), ?line {ok, Frames} = wsflush(Sock, false), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line {ok, []} = wsflush(Sock, true), ?line ok = close(Sock), ok. %% ---- test_badrsv_complex(BlockSz) -> io:format("badrsv_complex (rsv=5, blocksize=~p)~n", [BlockSz]), WSPath = "/websockets_example_endpoint.yaws", Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload = <<"small payload">>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame1 = #frame{opcode=?WS_OPCODE_TEXT, payload=Payload}, SndFrame2 = SndFrame1#frame{rsv=5}, SndFrame3 = #frame{opcode=?WS_OPCODE_PING, payload=Payload}, ?line ok = send_frame(Sock, SndFrame1, BlockSz), ?line ok = send_frame(Sock, SndFrame2, BlockSz), ?line ok = send_frame(Sock, SndFrame3, BlockSz), ?line {ok, [Frame1|Frames]} = wsflush(Sock, false), ?line ?WS_OPCODE_TEXT = Frame1#frame.opcode, ?line Payload = Frame1#frame.payload, ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line {ok, []} = wsflush(Sock, true), ?line ok = close(Sock), ok. %% ---- test_badopcodes() -> [test_badopcodes(O) || O <- [3,4,5,6,7,11,12,13,14,15]], ok. test_badopcodes(Opcode) -> io:format("badopcodes (opcode=~p)~n", [Opcode]), WSPath = "/websockets_example_endpoint.yaws", Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame = #frame{opcode=Opcode}, ?line ok = send_frame(Sock, SndFrame, all), ?line {ok, Frames} = wsflush(Sock, false), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line {ok, []} = wsflush(Sock, true), ?line ok = close(Sock), ok. %% ---- test_basic_fragmented_empty() -> io:format("basic_fragmented_empty~n", []), do_test_fragmented_empty("/websockets_example_endpoint.yaws"). test_advanced_fragmented_empty() -> io:format("advanced_fragmented_empty~n", []), do_test_fragmented_empty("/websockets_autobahn_endpoint.yaws"). do_test_fragmented_empty(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame1 = #frame{fin=false, opcode=?WS_OPCODE_TEXT}, SndFrame2 = #frame{fin=false, opcode=?WS_OPCODE_CONTINUATION}, SndFrame3 = #frame{opcode=?WS_OPCODE_CONTINUATION}, ?line ok = send_frame(Sock, SndFrame1, all), ?line ok = send_frame(Sock, SndFrame2, all), ?line ok = send_frame(Sock, SndFrame3, all), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, [Frame1|Frames]} = wsflush(Sock, true), ?line ?WS_OPCODE_TEXT = Frame1#frame.opcode, ?line <<>> = Frame1#frame.payload, ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock). %% ---- test_basic_fragmented_text_1() -> io:format("basic_fragmented_text_1~n", []), do_test_valid_fragmented_1("/websockets_example_endpoint.yaws", ?WS_OPCODE_TEXT). test_advanced_fragmented_text_1() -> io:format("advanced_fragmented_text_1~n", []), do_test_valid_fragmented_2("/websockets_autobahn_endpoint.yaws", ?WS_OPCODE_TEXT). test_basic_fragmented_binary_1() -> io:format("basic_fragmented_binary_1~n", []), do_test_valid_fragmented_1("/websockets_example_endpoint.yaws", ?WS_OPCODE_BINARY). test_advanced_fragmented_binary_1() -> io:format("advanced_fragmented_binary_1~n", []), do_test_valid_fragmented_1("/websockets_autobahn_endpoint.yaws", ?WS_OPCODE_BINARY). do_test_valid_fragmented_1(WSPath, Type) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload1 = <<"fragment1">>, Payload2 = <<"fragment2">>, Payload3 = <<"fragment3">>, Payload = <>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame1 = #frame{fin=false, opcode=Type, payload=Payload1}, SndFrame2 = #frame{fin=false, opcode=?WS_OPCODE_CONTINUATION, payload=Payload2}, SndFrame3 = #frame{opcode=?WS_OPCODE_CONTINUATION, payload=Payload3}, ?line ok = send_frame(Sock, SndFrame1, all), ?line ok = send_frame(Sock, SndFrame2, all), ?line ok = send_frame(Sock, SndFrame3, all), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, [Frame1|Frames]} = wsflush(Sock, true), ?line Type = Frame1#frame.opcode, ?line Payload = Frame1#frame.payload, ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock). %% ---- test_basic_fragmented_text_2() -> io:format("basic_fragmented_text_2~n", []), do_test_valid_fragmented_2("/websockets_example_endpoint.yaws", ?WS_OPCODE_TEXT). test_advanced_fragmented_text_2() -> io:format("advanced_fragmented_text_2~n", []), do_test_valid_fragmented_2("/websockets_autobahn_endpoint.yaws", ?WS_OPCODE_TEXT). test_basic_fragmented_binary_2() -> io:format("basic_fragmented_binary_2~n", []), do_test_valid_fragmented_2("/websockets_example_endpoint.yaws", ?WS_OPCODE_BINARY). test_advanced_fragmented_binary_2() -> io:format("advanced_fragmented_binary_2~n", []), do_test_valid_fragmented_2("/websockets_autobahn_endpoint.yaws", ?WS_OPCODE_BINARY). do_test_valid_fragmented_2(WSPath, Type) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload = <<"fragment">>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame1 = #frame{fin=false, opcode=Type}, SndFrame2 = #frame{fin=false, opcode=?WS_OPCODE_CONTINUATION, payload=Payload}, SndFrame3 = #frame{opcode=?WS_OPCODE_CONTINUATION}, ?line ok = send_frame(Sock, SndFrame1, all), ?line ok = send_frame(Sock, SndFrame2, all), ?line ok = send_frame(Sock, SndFrame3, all), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, [Frame1|Frames]} = wsflush(Sock, true), ?line Type = Frame1#frame.opcode, ?line Payload = Frame1#frame.payload, ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock). %% ---- test_basic_fragmented_ping() -> io:format("basic_fragmented_ping~n", []), do_test_invalid_fragmented("/websockets_example_endpoint.yaws", ?WS_OPCODE_PING). test_advanced_fragmented_ping() -> io:format("advanced_fragmented_ping~n", []), do_test_invalid_fragmented("/websockets_autobahn_endpoint.yaws", ?WS_OPCODE_PING). test_basic_fragmented_pong() -> io:format("basic_fragmented_pong~n", []), do_test_invalid_fragmented("/websockets_example_endpoint.yaws", ?WS_OPCODE_PONG). test_advanced_fragmented_pong() -> io:format("advanced_fragmented_pong~n", []), do_test_invalid_fragmented("/websockets_autobahn_endpoint.yaws", ?WS_OPCODE_PONG). test_basic_fragmented_close() -> io:format("basic_fragmented_close~n", []), do_test_invalid_fragmented("/websockets_example_endpoint.yaws", ?WS_OPCODE_CLOSE). test_advanced_fragmented_close() -> io:format("advanced_fragmented_ping~n", []), do_test_invalid_fragmented("/websockets_autobahn_endpoint.yaws", ?WS_OPCODE_CLOSE). do_test_invalid_fragmented(WSPath, Type) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload1 = <<"fragment1">>, Payload2 = <<"fragment2">>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame1 = #frame{fin=false, opcode=Type, payload=Payload1}, SndFrame2 = #frame{opcode=?WS_OPCODE_CONTINUATION, payload=Payload2}, ?line ok = send_frame(Sock, SndFrame1, all), ?line ok = send_frame(Sock, SndFrame2, all), ?line {ok, Frames} = wsflush(Sock, false), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line {ok, []} = wsflush(Sock, true), ?line ok = close(Sock). %% ---- test_basic_fragmented_text_with_ping() -> io:format("basic_fragmented_text_with_ping~n", []), do_test_fragmented_with_ping("/websockets_example_endpoint.yaws"). test_advanced_fragmented_text_with_ping() -> io:format("advanced_fragmented_text_with_ping~n", []), do_test_fragmented_with_ping("/websockets_autobahn_endpoint.yaws"). do_test_fragmented_with_ping(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload1 = <<"fragment1">>, Payload2 = <<"fragment2">>, Payload = <>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame1 = #frame{fin=false, opcode=?WS_OPCODE_TEXT, payload=Payload1}, SndFrame2 = #frame{opcode=?WS_OPCODE_PING}, SndFrame3 = #frame{opcode=?WS_OPCODE_CONTINUATION, payload=Payload2}, ?line ok = send_frame(Sock, SndFrame1, all), ?line ok = send_frame(Sock, SndFrame2, all), ?line ok = send_frame(Sock, SndFrame3, all), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, [Frame1, Frame2|Frames]} = wsflush(Sock, true), ?line ?WS_OPCODE_PONG = Frame1#frame.opcode, ?line ?WS_OPCODE_TEXT = Frame2#frame.opcode, ?line Payload = Frame2#frame.payload, ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock). %% --- test_basic_fragmented_text_with_pong() -> io:format("basic_fragmented_text_with_pong~n", []), do_test_fragmented_with_pong("/websockets_example_endpoint.yaws"). test_advanced_fragmented_text_with_pong() -> io:format("advanced_fragmented_text_with_pong~n", []), do_test_fragmented_with_pong("/websockets_autobahn_endpoint.yaws"). do_test_fragmented_with_pong(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload1 = <<"fragment1">>, Payload2 = <<"fragment2">>, Payload = <>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame1 = #frame{fin=false, opcode=?WS_OPCODE_TEXT, payload=Payload1}, SndFrame2 = #frame{opcode=?WS_OPCODE_PONG}, SndFrame3 = #frame{opcode=?WS_OPCODE_CONTINUATION, payload=Payload2}, ?line ok = send_frame(Sock, SndFrame1, all), ?line ok = send_frame(Sock, SndFrame2, all), ?line ok = send_frame(Sock, SndFrame3, all), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, [Frame1|Frames]} = wsflush(Sock, true), ?line ?WS_OPCODE_TEXT = Frame1#frame.opcode, ?line Payload = Frame1#frame.payload, ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock). %% ---- test_basic_badfragmented_1() -> io:format("basic_badfragmented_1 (fin=true)~n", []), do_test_badfragmented("/websockets_example_endpoint.yaws", true). test_basic_badfragmented_2() -> io:format("basic_badfragmented_2 (fin=false)~n", []), do_test_badfragmented("/websockets_example_endpoint.yaws", false). test_advanced_badfragmented_1() -> io:format("advanced_badfragmented_1 (fin=true)~n", []), do_test_badfragmented("/websockets_autobahn_endpoint.yaws", true). test_advanced_badfragmented_2() -> io:format("advanced_badfragmented_2 (fin=false)~n", []), do_test_badfragmented("/websockets_autobahn_endpoint.yaws", false). do_test_badfragmented(WSPath, Fin) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload = <<"small payload">>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame1 = #frame{fin=Fin, opcode=?WS_OPCODE_CONTINUATION, payload=Payload}, SndFrame2 = #frame{opcode=?WS_OPCODE_TEXT, payload=Payload}, ?line ok = send_frame(Sock, SndFrame1, all), ?line ok = send_frame(Sock, SndFrame2, all), ?line {ok, Frames} = wsflush(Sock, false), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line {ok, []} = wsflush(Sock, true), ?line ok = close(Sock). %% --- test_basic_badfragmented_nocontinuation() -> io:format("basic_badfragmented_nocontinuation~n", []), do_test_badfragmented_nocontinuation("/websockets_example_endpoint.yaws"). test_advanced_badfragmented_nocontinuation() -> io:format("advanced_badfragmented_nocontinuation~n", []), do_test_badfragmented_nocontinuation("/websockets_autobahn_endpoint.yaws"). do_test_badfragmented_nocontinuation(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload1 = <<"fragment1">>, Payload2 = <<"fragment2">>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame1 = #frame{fin=false, opcode=?WS_OPCODE_TEXT, payload=Payload1}, SndFrame2 = #frame{fin=false, opcode=?WS_OPCODE_TEXT, payload=Payload2}, ?line ok = send_frame(Sock, SndFrame1, all), ?line ok = send_frame(Sock, SndFrame2, all), ?line {ok, Frames} = wsflush(Sock, false), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line {ok, []} = wsflush(Sock, true), ?line ok = close(Sock). %% ---- test_basic_unfragmented_valid_utf8_text(BlockSz) -> io:format("basic_unfragmented_valid_utf8_text (blocksize=~p)~n", [BlockSz]), do_test_unfragmented_valid_utf8("/websockets_example_endpoint.yaws", BlockSz). test_advanced_unfragmented_valid_utf8_text(BlockSz) -> io:format("advanced_unfragmented_valid_utf8_text (blocksize=~p)~n", [BlockSz]), do_test_unfragmented_valid_utf8("/websockets_autobahn_endpoint.yaws", BlockSz). -ifdef(HAVE_BAD_UNICODE). -define(BAD_UNICODE, true). -else. -define(BAD_UNICODE, false). -endif. do_test_unfragmented_valid_utf8(WSPath, BlockSz) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), Fun = fun(Payload) -> SndFrame = #frame{opcode=?WS_OPCODE_TEXT, payload=Payload}, ?line ok = send_frame(Sock, SndFrame, BlockSz), ?line {ok, RcvFrame} = read_frame(Sock), ?line ?WS_OPCODE_TEXT = RcvFrame#frame.opcode, ?line Payload = RcvFrame#frame.payload end, Fun(<<16#ce,16#ba>>), Fun(<<16#ce,16#ba,16#e1,16#bd,16#b9>>), Fun(<<16#ce,16#ba,16#e1,16#bd,16#b9,16#cf,16#83>>), Fun(<<16#ce,16#ba,16#e1,16#bd,16#b9,16#cf,16#83,16#ce,16#bc>>), Fun(<<16#ce,16#ba,16#e1,16#bd,16#b9,16#cf,16#83,16#ce,16#bc, 16#ce,16#b5>>), Fun(<<"Hello-",16#c2,16#b5,$@,16#c3,16#9f,16#c3,16#b6,16#c3,16#a4, 16#c3,16#bc,16#c3,16#a0,16#c3,16#a1,"-UTF-8!!">>), Fun(<<16#00>>), Fun(<<16#c2,16#80>>), Fun(<<16#e0,16#a0,16#80>>), Fun(<<16#f0,16#90,16#80,16#80>>), Fun(<<16#7f>>), Fun(<<16#df,16#bf>>), case ?BAD_UNICODE of true -> ok; false -> Fun(<<16#ef,16#bf,16#bf>>) end, Fun(<<16#f4,16#8f,16#bf,16#bf>>), Fun(<<16#ed,16#9f,16#bf>>), Fun(<<16#ee,16#80,16#80>>), Fun(<<16#ef,16#bf,16#bd>>), Fun(<<16#f4,16#8f,16#bf,16#bf>>), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_fragmented_valid_utf8_text(FragSz) -> io:format("basic_fragmented_valid_utf8_text (fragsize=~p)~n", [FragSz]), do_test_fragmented_valid_utf8("/websockets_example_endpoint.yaws", FragSz). test_advanced_fragmented_valid_utf8_text(FragSz) -> io:format("advanced_fragmented_valid_utf8_text (fragsize=~p)~n", [FragSz]), do_test_fragmented_valid_utf8("/websockets_autobahn_endpoint.yaws", FragSz). do_test_fragmented_valid_utf8(WSPath, FragSz) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload1 = <<"Hello-",16#c2,16#b5,$@,16#c3,16#9f,16#c3,16#b6,16#c3,16#a4>>, Payload2 = <<16#c3,16#bc,16#c3,16#a0,16#c3,16#a1,"-UTF-8!!">>, Payload = <>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), Payloads = fragment_payload(Payload1, FragSz) ++ fragment_payload(Payload2, FragSz), [First|Rest0] = Payloads, [Last|Rest1] = lists:reverse(Rest0), Middles = lists:reverse(Rest1), FirstFrame = #frame{fin=false, opcode=?WS_OPCODE_TEXT, payload=First}, LastFrame = #frame{opcode=?WS_OPCODE_CONTINUATION, payload=Last}, MiddleFrames = lists:map(fun(P) -> #frame{fin=false, opcode=?WS_OPCODE_CONTINUATION, payload=P} end, Middles), ?line ok = send_frame(Sock, FirstFrame, all), lists:foreach(fun(F) -> ?line ok = send_frame(Sock, F, all) end, MiddleFrames), ?line ok = send_frame(Sock, LastFrame, all), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, [Frame1|Frames]} = wsflush(Sock, true), ?line ?WS_OPCODE_TEXT = Frame1#frame.opcode, ?line Payload = Frame1#frame.payload, ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_unfragmented_invalid_utf8_text(BlockSz) -> io:format("basic_unfragmented_invalid_utf8_text (blocksize=~p)~n", [BlockSz]), do_test_unfragmented_invalid_utf8("/websockets_example_endpoint.yaws", BlockSz). test_advanced_unfragmented_invalid_utf8_text(BlockSz) -> io:format("advanced_unfragmented_invalid_utf8_text (blocksize=~p)~n", [BlockSz]), do_test_unfragmented_invalid_utf8("/websockets_autobahn_endpoint.yaws", BlockSz). do_test_unfragmented_invalid_utf8(WSPath, BlockSz) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Fun = fun(Payload) -> ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame = #frame{opcode=?WS_OPCODE_TEXT, payload=Payload}, ?line ok = send_frame(Sock, SndFrame, BlockSz), ?line {ok, Frames} = wsflush(Sock, false), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_INVALID_PAYLOAD]), ?line {ok, []} = wsflush(Sock, true), ?line ok = close(Sock) end, Fun(<<16#cd>>), Fun(<<16#ce,16#ba,16#e1>>), Fun(<<16#ce,16#ba,16#e1,16#bd>>), Fun(<<16#ce,16#ba,16#e1,16#bd,16#b9,16#cf>>), Fun(<<16#ce,16#ba,16#e1,16#bd,16#b9,16#cf,16#83,16#ce>>), Fun(<<16#ce,16#ba,16#e1,16#bd,16#b9,16#cf,16#83,16#ce,16#bc,16#ce>>), Fun(<<16#ce,16#ba,16#e1,16#bd,16#b9,16#cf,16#83,16#ce,16#bc,16#ce, 16#b5,16#ed,16#a0,16#80,16#65,16#64,16#69,16#74,16#65,16#64>>), Fun(<<16#f8,16#88,16#80,16#80,16#80>>), Fun(<<16#fc,16#84,16#80,16#80,16#80,16#80>>), Fun(<<16#f7,16#bf,16#bf,16#bf>>), Fun(<<16#fb,16#bf,16#bf,16#bf,16#bf>>), Fun(<<16#fd,16#bf,16#bf,16#bf,16#bf,16#bf>>), Fun(<<16#f4,16#90,16#80,16#80>>), Fun(<<16#80>>), Fun(<<16#bf>>), Fun(<<16#80,16#bf>>), Fun(<<16#80,16#bf,16#80>>), Fun(<<16#80,16#bf,16#80,16#bf>>), Fun(<<16#80,16#bf,16#80,16#bf,16#80>>), Fun(<<16#80,16#bf,16#80,16#bf,16#80,16#bf>>), Fun(<<16#80,16#81,16#82,16#83,16#84,16#85,16#86,16#87,16#88,16#89,16#8a, 16#8b,16#8c,16#8d,16#8e,16#8f,16#90,16#91,16#92,16#93,16#94,16#95, 16#96,16#97,16#98,16#99,16#9a,16#9b,16#9c,16#9d,16#9e,16#9f,16#a0, 16#a1,16#a2,16#a3,16#a4,16#a5,16#a6,16#a7,16#a8,16#a9,16#aa,16#ab, 16#ac,16#ad,16#ae,16#af,16#b0,16#b1,16#b2,16#b3,16#b4,16#b5,16#b6, 16#b7,16#b8,16#b9,16#ba,16#bb,16#bc,16#bd,16#be>>), ok. %% ---- test_basic_fragmented_invalid_utf8_text(FragSz) -> io:format("basic_fragmented_invalid_utf8_text (fragsize=~p)~n", [FragSz]), do_test_fragmented_invalid_utf8("/websockets_example_endpoint.yaws", FragSz). test_advanced_fragmented_invalid_utf8_text(FragSz) -> io:format("advanced_fragmented_invalid_utf8_text (fragsize=~p)~n", [FragSz]), do_test_fragmented_invalid_utf8("/websockets_autobahn_endpoint.yaws", FragSz). do_test_fragmented_invalid_utf8(WSPath, FragSz) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", Payload1 = <<16#ce,16#ba,16#e1,16#bd,16#b9,16#cf,16#83,16#ce,16#bc,16#ce>>, Payload2 = <<16#b5,16#ed,16#a0,16#80,16#65,16#64,16#69,16#74,16#65,16#64>>, ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), Payloads = fragment_payload(Payload1, FragSz) ++ fragment_payload(Payload2, FragSz), [First|Rest0] = Payloads, [Last|Rest1] = lists:reverse(Rest0), Middles = lists:reverse(Rest1), FirstFrame = #frame{fin=false, opcode=?WS_OPCODE_TEXT, payload=First}, LastFrame = #frame{opcode=?WS_OPCODE_CONTINUATION, payload=Last}, MiddleFrames = lists:map(fun(P) -> #frame{fin=false, opcode=?WS_OPCODE_CONTINUATION, payload=P} end, Middles), ?line ok = send_frame(Sock, FirstFrame, all), lists:foreach(fun(F) -> ?line ok = send_frame(Sock, F, all) end, MiddleFrames), ?line ok = send_frame(Sock, LastFrame, all), ?line {ok, Frames} = wsflush(Sock, false), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_INVALID_PAYLOAD]), ?line {ok, []} = wsflush(Sock, true), ?line ok = close(Sock), ok. %% ---- test_basic_2_closes() -> io:format("basic_2_closes~n", []), do_test_2_closes("/websockets_example_endpoint.yaws"). test_advanced_2_closes() -> io:format("advanced_2_closes~n", []), do_test_2_closes("/websockets_autobahn_endpoint.yaws"). do_test_2_closes(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_close_ping() -> io:format("basic_close_ping~n", []), do_test_close_ping("/websockets_example_endpoint.yaws"). test_advanced_close_ping() -> io:format("advanced_close_ping~n", []), do_test_close_ping("/websockets_autobahn_endpoint.yaws"). do_test_close_ping(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line ok = send_frame(Sock, #frame{opcode=?WS_OPCODE_PING}, all), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_close_text() -> io:format("basic_close_text~n", []), do_test_close_text("/websockets_example_endpoint.yaws"). test_advanced_close_text() -> io:format("advanced_close_text~n", []), do_test_close_text("/websockets_autobahn_endpoint.yaws"). do_test_close_text(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line ok = send_frame(Sock, #frame{opcode=?WS_OPCODE_TEXT}, all), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_fragtext_close_fragtext() -> io:format("basic_fragtext_close_fragtext~n", []), do_test_fragtext_close_fragtext("/websockets_example_endpoint.yaws"). test_advanced_fragtext_close_fragtext() -> io:format("advanced_fragtext_close_fragtext~n", []), do_test_fragtext_close_fragtext("/websockets_autobahn_endpoint.yaws"). do_test_fragtext_close_fragtext(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), ?line ok = send_frame(Sock, #frame{fin=false, opcode=?WS_OPCODE_TEXT}, all), ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line ok = send_frame(Sock, #frame{opcode=?WS_OPCODE_CONTINUATION}, all), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_close_empty() -> io:format("basic_close_empty~n", []), do_test_close_empty("/websockets_example_endpoint.yaws"). test_advanced_close_empty() -> io:format("advanced_close_empty~n", []), do_test_close_empty("/websockets_autobahn_endpoint.yaws"). do_test_close_empty(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), ?line ok = gen_tcp:send(Sock, <<136,0>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_close_toosmall() -> io:format("basic_close_toosmall~n", []), do_test_close_toosmall("/websockets_example_endpoint.yaws"). test_advanced_close_toosmall() -> io:format("advanced_close_toosmall~n", []), do_test_close_toosmall("/websockets_autobahn_endpoint.yaws"). do_test_close_toosmall(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), ?line ok = gen_tcp:send(Sock, <<136,1,0>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line ok = close(Sock), ok. %% ---- test_basic_close_statusonly() -> io:format("basic_close_statusonly~n", []), do_test_close_statusonly("/websockets_example_endpoint.yaws"). test_advanced_close_statusonly() -> io:format("advanced_close_statusonly~n", []), do_test_close_statusonly("/websockets_autobahn_endpoint.yaws"). do_test_close_statusonly(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), ?line ok = gen_tcp:send(Sock, <<136,2,1000:16/big>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_close_with_reason() -> io:format("basic_close_with_reason~n", []), do_test_close_with_reason("/websockets_example_endpoint.yaws"). test_advanced_close_with_reason() -> io:format("advanced_close_with_reason~n", []), do_test_close_with_reason("/websockets_autobahn_endpoint.yaws"). do_test_close_with_reason(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), ?line ok = gen_tcp:send(Sock, <<136,4,1000:16/big,"Ok">>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_close_limit_size() -> io:format("basic_close_limit_size~n", []), do_test_close_limit_size("/websockets_example_endpoint.yaws"). test_advanced_close_limit_size() -> io:format("advanced_close_limit_size~n", []), do_test_close_limit_size("/websockets_autobahn_endpoint.yaws"). do_test_close_limit_size(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), Reason = list_to_binary(lists:duplicate(123, $*)), ?line ok = gen_tcp:send(Sock, <<136,125,1000:16/big,Reason/binary>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok. %% ---- test_basic_close_toolong() -> io:format("basic_close_toolong~n", []), do_test_close_toolong("/websockets_example_endpoint.yaws"). test_advanced_close_toolong() -> io:format("advanced_close_toolong~n", []), do_test_close_toolong("/websockets_autobahn_endpoint.yaws"). do_test_close_toolong(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), Reason = list_to_binary(lists:duplicate(124, $*)), ?line ok = gen_tcp:send(Sock, <<136,126,1000:16/big,Reason/binary>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line ok = close(Sock), ok. %% ---- test_basic_close_invalid_utf8() -> io:format("basic_close_invalid_utf8~n", []), do_test_close_invalid_utf8("/websockets_example_endpoint.yaws"). test_advanced_close_invalid_utf8() -> io:format("advanced_close_invalid_utf8~n", []), do_test_close_invalid_utf8("/websockets_autobahn_endpoint.yaws"). do_test_close_invalid_utf8(WSPath) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), Reason = <<16#ce,16#ba,16#e1,16#bd,16#b9,16#cf,16#83,16#ce,16#bc,16#ce, 16#b5,16#ed,16#a0,16#80,16#65,16#64,16#69,16#74,16#65,16#64>>, ?line ok = gen_tcp:send(Sock, <<136,22,1000:16/big,Reason/binary>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_INVALID_PAYLOAD]), ?line ok = close(Sock), ok. %% ---- test_basic_close_valid_codes() -> lists:foreach( fun(Code) -> io:format("basic_close_valid_codes (code=~p)~n", [Code]), do_test_close_valid_code("/websockets_example_endpoint.yaws", Code) end, [1000,1001,1002,1003,1007,1008,1009,1010,1011,3000,3999,4000,4999] ). test_advanced_close_valid_codes() -> lists:foreach( fun(Code) -> io:format("advanced_close_valid_codes (code=~p)~n", [Code]), do_test_close_valid_code("/websockets_autobahn_endpoint.yaws", Code) end, [1000,1001,1002,1003,1007,1008,1009,1010,1011,3000,3999,4000,4999] ). do_test_close_valid_code(WSPath, Code) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), ?line ok = wsclose(Sock, Code, <<>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [Code]), ?line ok = close(Sock), ok. %% ---- test_basic_close_invalid_codes() -> lists:foreach( fun(Code) -> io:format("basic_close_invalid_codes (code=~p)~n", [Code]), do_test_close_invalid_code("/websockets_example_endpoint.yaws", Code) end, [0,999,1004,1005,1006,1012,1013,1014,1015,1016,1100,2000,2999,5000,65536] ). test_advanced_close_invalid_codes() -> lists:foreach( fun(Code) -> io:format("advanced_close_invalid_codes (code=~p)~n", [Code]), do_test_close_invalid_code("/websockets_autobahn_endpoint.yaws", Code) end, [0,999,1004,1005,1006,1012,1013,1014,1015,1016,1100,2000,2999,5000,65536] ). do_test_close_invalid_code(WSPath, Code) -> Key = "dGhlIHNhbXBsZSBub25jZQ==", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), ?line ok = wsclose(Sock, Code, <<>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line ok = close(Sock), ok. %% ---- test_close_timeout() -> io:format("close_timeout (tout=5sec)~n",[]), Key = "dGhlIHNhbXBsZSBub25jZQ==", WSPath = "/websockets_example_endpoint.yaws?extversion=true", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame = #frame{opcode=?WS_OPCODE_TEXT, payload = <<"bye">>}, ?line ok = send_frame(Sock, SndFrame, all), ?line {ok, Frames} = wsflush(Sock, false), LastFrame = lists:last(Frames), ?line true = is_valid_close_frame([LastFrame], [?WS_STATUS_NORMAL]), timer:sleep(5500), %% Waiting for the timeout ?line {error, closed} = gen_tcp:recv(Sock, 0), ?line ok = close(Sock), ok. %% ---- test_keepalive_timeout() -> io:format("keepalive_timeout (timeout=5sec, grace_period=2sec, drop_on_timeout=true)~n",[]), Key = "dGhlIHNhbXBsZSBub25jZQ==", WSPath = "/websockets_example_endpoint.yaws?keepalive=true&timeout=5000&drop=true", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), timer:sleep(5500), ?line {ok, RcvFrame1} = read_frame(Sock), ?line ?WS_OPCODE_PING = RcvFrame1#frame.opcode, ?line ok = send_frame(Sock, #frame{opcode=?WS_OPCODE_PONG}, all), timer:sleep(5500), ?line {ok, RcvFrame2} = read_frame(Sock), ?line ?WS_OPCODE_PING = RcvFrame2#frame.opcode, timer:sleep(2000), ?line {error, closed} = gen_tcp:recv(Sock, 0), ?line ok = close(Sock), ok. %% ---- test_too_big_frame() -> io:format("too_big_frame (> 16 Mo)~n",[]), Key = "dGhlIHNhbXBsZSBub25jZQ==", WSPath = "/websockets_example_endpoint.yaws", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), Payload1 = crypto:rand_bytes(16*1024*1024), SndFrame1 = #frame{opcode=?WS_OPCODE_BINARY, payload=Payload1}, ?line ok = send_frame(Sock, SndFrame1, all), ?line {ok, RcvFrame} = read_frame(Sock), ?line ?WS_OPCODE_BINARY = RcvFrame#frame.opcode, ?line Payload1 = RcvFrame#frame.payload, Payload2 = <<0, Payload1/binary>>, SndFrame2 = #frame{opcode=?WS_OPCODE_BINARY, payload=Payload2}, ?line {ok, Closed} = case send_frame(Sock, SndFrame2, all) of ok -> {ok, false}; {error, closed} -> {ok, true} end, ?line {ok, Frames} = wsflush(Sock, true), ?line true = case Closed of false -> is_valid_close_frame(Frames, [?WS_STATUS_MSG_TOO_BIG]); true -> true end, ?line ok = close(Sock), ok. %% ---- test_close_unmasked_frame() -> io:format("close_unmasked_frame~n",[]), Key = "dGhlIHNhbXBsZSBub25jZQ==", WSPath = "/websockets_example_endpoint.yaws?close_unmasked=true", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), %% unmasked SndFrame = #frame{opcode=?WS_OPCODE_TEXT, payload = <<"unmasked">>}, ?line ok = send_frame(Sock, SndFrame, all), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_PROTO_ERROR]), ?line ok = close(Sock), ok. %% ---- test_too_big_message() -> io:format("too_big_message (> 16 Mo)~n",[]), Key = "dGhlIHNhbXBsZSBub25jZQ==", WSPath = "/websockets_example_endpoint.yaws", ?line {ok, Sock} = open("localhost", 8000), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), Payload1 = crypto:rand_bytes(16*1024*1024), <> = Payload1, SndFrame1 = #frame{fin=false, opcode=?WS_OPCODE_BINARY, payload=Frag1}, SndFrame2 = #frame{fin=false, opcode=?WS_OPCODE_CONTINUATION, payload=Frag2}, SndFrame3 = #frame{fin=false, opcode=?WS_OPCODE_CONTINUATION, payload=Frag3}, SndFrame4 = #frame{opcode=?WS_OPCODE_CONTINUATION, payload=Frag4}, ?line ok = send_frame(Sock, SndFrame1, all), ?line ok = send_frame(Sock, SndFrame2, all), ?line ok = send_frame(Sock, SndFrame3, all), ?line ok = send_frame(Sock, SndFrame4, all), ?line {ok, RcvFrame} = read_frame(Sock), ?line ?WS_OPCODE_BINARY = RcvFrame#frame.opcode, ?line Payload1 = RcvFrame#frame.payload, Payload2 = <<0, Payload1/binary>>, <> = Payload2, SndFrame5 = #frame{fin=false, opcode=?WS_OPCODE_BINARY, payload=Frag5}, SndFrame6 = #frame{fin=false, opcode=?WS_OPCODE_CONTINUATION, payload=Frag6}, SndFrame7 = #frame{fin=false, opcode=?WS_OPCODE_CONTINUATION, payload=Frag7}, SndFrame8 = #frame{opcode=?WS_OPCODE_CONTINUATION, payload=Frag8}, ?line ok = send_frame(Sock, SndFrame5, all), ?line ok = send_frame(Sock, SndFrame6, all), ?line ok = send_frame(Sock, SndFrame7, all), ?line ok = send_frame(Sock, SndFrame8, all), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_MSG_TOO_BIG]), ?line ok = close(Sock), ok. %% ---- test_secure_websocket() -> io:format("secure_websocket~n",[]), Key = "dGhlIHNhbXBsZSBub25jZQ==", WSPath = "/websockets_example_endpoint.yaws", ok = application:start(crypto), ok = application:start(asn1), ok = application:start(public_key), ok = application:start(ssl), ?line {ok, Sock} = sslopen("localhost", 8443), ?line {ok, {101, _}} = wsopen(Sock, Key, WSPath, "http://localhost", 13), SndFrame = #frame{opcode=?WS_OPCODE_TEXT, payload = <<"small payload">>}, ?line ok = send_frame(Sock, SndFrame, all), ?line {ok, RcvFrame} = read_frame(Sock), ?line ?WS_OPCODE_TEXT = RcvFrame#frame.opcode, ?line <<"small payload">> = RcvFrame#frame.payload, ?line ok = wsclose(Sock, ?WS_STATUS_NORMAL, <<>>), ?line {ok, Frames} = wsflush(Sock, true), ?line true = is_valid_close_frame(Frames, [?WS_STATUS_NORMAL]), ?line ok = close(Sock), ok = application:stop(ssl), ok = application:stop(public_key), ok = application:stop(asn1), ok = application:stop(crypto), ok. %% ======================================================================= open(Host, Port) -> Opts = [{send_timeout, 2000}, binary, {packet, raw}, {active, false}], gen_tcp:connect(Host, Port, Opts). sslopen(Host, Port) -> Opts = [{send_timeout, 2000}, binary, {packet, raw}, {active, false}], case ssl:connect(Host, Port, Opts) of {ok, Sock} -> {ok, {ssl, Sock}}; {error, Reason} -> {error, Reason} end. close(Sock) -> case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:close(SslSock); undefined -> gen_tcp:close(Sock) end. %% ---- wsopen(Sock, Key, Path, Origin, Vsn) -> Handshake = ["GET ", Path, " HTTP/1.1\r\n", "Host: localhost\r\n", "Upgrade: websocket\r\n", "Connection: Upgrade\r\n", "Sec-WebSocket-Key: ", Key, "\r\n", "Origin: ", Origin, "\r\n", "Sec-WebSocket-Version: ", integer_to_list(Vsn), "\r\n", "\r\n"], case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:send(SslSock, Handshake); undefined -> gen_tcp:send(Sock, Handshake) end, read_handshake_response(Sock). wsclose(Sock, Status, Msg) -> Fin = 1, Rsv = 0, Mask = 0, Opcode = ?WS_OPCODE_CLOSE, Payload= <>, Len = byte_size(Payload), Frame = if Len < 126 -> <>; Len < 65536 -> <>; true -> <> end, case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:send(SslSock, Frame); undefined -> gen_tcp:send(Sock, Frame) end. %% ---- wsflush(Sock, WithTcpClose) -> wsflush(Sock, WithTcpClose, []). wsflush(Sock, WithTcpClose, Acc) -> case read_frame(Sock) of {ok, Frame} -> case Frame#frame.opcode of ?WS_OPCODE_CLOSE when WithTcpClose == false -> {ok, lists:reverse([Frame|Acc])}; _ -> wsflush(Sock, WithTcpClose, [Frame|Acc]) end; {error, closed} -> {ok, lists:reverse(Acc)}; {error, Reason} -> {error, Reason} end. %% ---- is_valid_handshake_hash(Key, Hash) -> Salted = Key ++ "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", HashBin = ?CRYPTO_HASH(Salted), Hash == base64:encode_to_string(HashBin). %% ---- is_valid_close_frame([], _) -> io:format(" WARNING: Connection closed by server without Close frame~n"), true; is_valid_close_frame([#frame{opcode=?WS_OPCODE_CLOSE, payload=Payload}|Rest], Codes) -> case Rest of [] -> case Payload of <<>> -> lists:member(?WS_STATUS_NORMAL, Codes); <> -> case lists:member(Status, Codes) of true -> true; false -> io:format(" ERROR: Bad status code in close" " frame: status=~p~n", [Status]), false end end; _ -> io:format(" ERROR: Remaining frames after the Close frame~n") end; is_valid_close_frame([#frame{opcode=OpCode}|_], _) -> io:format(" ERROR: Not a close frame: opcode=~p~n", [OpCode]), false. %% ---- apply_loop(0, _Fun, _Args, ExpectedRes) -> ExpectedRes; apply_loop(N, Fun, Args, ExpectedRes) -> ?line ExpectedRes = apply(Fun, Args), apply_loop(N-1, Fun, Args, ExpectedRes). %% ---- fragment_payload(Payload, all) -> [Payload]; fragment_payload(<<>>, _) -> []; fragment_payload(Payload, FragSz) -> case Payload of <> -> [Frag | fragment_payload(Rest, FragSz)]; Rest -> [Rest] end. %% ---- read_handshake_response(Sock) -> Res = case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:setopts(SslSock, [{packet, http}, {packet_size, 16#4000}]), ssl:recv(SslSock, 0, 2000); undefined -> inet:setopts(Sock, [{packet, http}, {packet_size, 16#4000}]), gen_tcp:recv(Sock, 0, 2000) end, case Res of {ok, {http_response, _, Status, _}} -> case yaws_api:get_sslsocket(Sock) of {ok, SslSock1} -> ssl:setopts(SslSock1,[{packet,httph},{packet_size,16#4000}]); undefined -> inet:setopts(Sock, [{packet,httph},{packet_size,16#4000}]) end, Resp = read_handshake_response(Sock, Status, []), case yaws_api:get_sslsocket(Sock) of {ok, SslSock2} -> ssl:setopts(SslSock2,[binary, {packet, raw}]); undefined -> inet:setopts(Sock, [binary, {packet, raw}]) end, Resp; {ok, Error} -> {error, Error}; {error, Reason} -> {error, Reason} end. read_handshake_response(Sock, Status, Acc) -> Res = case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:recv(SslSock, 0, 2000); undefined -> gen_tcp:recv(Sock, 0, 2000) end, case Res of {ok, {http_header, _, Name, _, Value}} when is_atom(Name) -> Name1 = string:to_lower(atom_to_list(Name)), read_handshake_response(Sock, Status, [{Name1, Value}|Acc]); {ok, {http_header, _, Name, _, Value}} -> Name1 = string:to_lower(Name), read_handshake_response(Sock, Status, [{Name1, Value}|Acc]); {ok, http_eoh} -> {ok, {Status, Acc}}; {ok, Error} -> {error, Error}; {error, Reason} -> {error, Reason} end. %% ---- read_frame(Sock) -> case read_frame_header(Sock) of {ok, #frame{mask=undefined}=Frame} -> {ok, Frame}; {ok, Frame} -> Payload = mask(Frame#frame.mask, Frame#frame.payload), {ok, Frame#frame{payload=Payload}}; {error, Reason} -> {error, Reason} end. read_frame_header(Sock) -> case do_recv(Sock, 2) of {ok, <>} -> Frame = #frame{fin = bit_to_boolean(Fin), rsv = Rsv, opcode = Opcode, masked = bit_to_boolean(MaskBit)}, case read_frame_length(Sock, Len) of {ok, Length} -> read_frame_payload(Sock, Frame, Length); {error, Reason} -> {error, Reason} end; {error, Reason} -> {error, Reason} end. read_frame_length(Sock, 126) -> case do_recv(Sock, 2) of {ok, <>} -> {ok, Length}; {error, Reason} -> {error, Reason} end; read_frame_length(Sock, 127) -> case do_recv(Sock, 8) of {ok, <>} -> {ok, Length}; {error, Reason} -> {error, Reason} end; read_frame_length(_Sock, Length) -> {ok, Length}. read_frame_mask(Sock) -> case do_recv(Sock, 4) of {ok, Mask} -> {ok, Mask}; {error, Reason} -> {error, Reason} end. read_frame_payload(Sock, #frame{masked=true, mask=undefined}=Frame, Length) -> case read_frame_mask(Sock) of {ok, Mask} -> read_frame_payload(Sock, Frame#frame{mask=Mask}, Length); {error, Reason} -> {error, Reason} end; read_frame_payload(Sock, Frame, Length) -> case do_recv(Sock, Length) of {ok, Payload} -> {ok, Frame#frame{payload=Payload}}; {error, Reason} -> {error, Reason} end. %% ---- send_frame(Sock, Frame, BlockSz) -> Fin = boolean_to_bit(Frame#frame.fin), Rsv = Frame#frame.rsv, Opcode = Frame#frame.opcode, MaskBit = boolean_to_bit(Frame#frame.masked), Mask = case Frame#frame.mask of undefined -> <<>>; M -> M end, Data = mask(Mask, Frame#frame.payload), Len = byte_size(Data), Packet = if Len < 126 -> <>; Len < 65536 -> <>; true -> <> end, case BlockSz of all -> case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:send(SslSock, Packet); undefined -> gen_tcp:send(Sock, Packet) end; _ -> do_send(Sock, Packet, BlockSz) end. do_send(_Sock, <<>>, _BlockSz) -> ok; do_send(Sock, Packet, BlockSz) -> case Packet of <> -> case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:send(SslSock, Block); undefined -> gen_tcp:send(Sock, Block) end, do_send(Sock, Rest, BlockSz); _ -> case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:send(SslSock, Packet); undefined -> gen_tcp:send(Sock, Packet) end end. %% ---- mask(MaskBin, Data) -> list_to_binary(rmask(MaskBin, Data)). rmask(_,<<>>) -> [<<>>]; rmask(<<>>, Data) -> [Data]; rmask(MaskBin = <>, <>) -> Masked = Mask bxor Data, [<> | rmask(MaskBin, Rest)]; rmask(<>, <>) -> Masked = Mask bxor Data, [<>]; rmask(<>, <>) -> Masked = Mask bxor Data, [<>]; rmask(<>, <>) -> Masked = Mask bxor Data, [<>]. %% ---- bit_to_boolean(1) -> true; bit_to_boolean(0) -> false. boolean_to_bit(true) -> 1; boolean_to_bit(false) -> 0. %% ---- do_recv(Sock, Sz) -> do_recv(Sock, Sz, []). do_recv(_Sock, 0, Acc) -> {ok, list_to_binary(lists:reverse(Acc))}; do_recv(Sock, Sz, Acc) -> Res = case yaws_api:get_sslsocket(Sock) of {ok, SslSock} -> ssl:recv(SslSock, Sz, 1000); undefined -> gen_tcp:recv(Sock, Sz, 1000) end, case Res of {ok, Bin} -> do_recv(Sock, Sz - byte_size(Bin), [Bin|Acc]); {error, Reason} -> {error, Reason} end. yaws-2.0.2/test/t10/yaws.conf.in0000664000175000017500000000143312605311413013240 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 port = 8000 listen = 0.0.0.0 docroot = @abs_top_srcdir@/www port = 8443 listen = 0.0.0.0 docroot = @abs_top_srcdir@/www keyfile = @abs_top_srcdir@/ssl/yaws-key.pem certfile = @abs_top_srcdir@/ssl/yaws-cert.pem depth = 0 yaws-2.0.2/test/t10/Makefile.am0000664000175000017500000000100712605311413013032 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl EXTRA_DIST = $(MODULES) EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/t2/0000775000175000017500000000000012605312015011000 500000000000000yaws-2.0.2/test/t2/Makefile.in0000664000175000017500000003752112605311446013004 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t2 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl \ appmod1.erl \ appmod2.erl \ appmod3.erl \ cache_appmod_test.erl \ dispatchmod_tester.erl \ flushtest.erl \ forwarded_for_test.erl \ jsontest.erl \ phptest.erl \ posttest.erl \ reentranttest.erl \ rewritetest.erl \ shapertest.erl \ streamtest.erl \ throwtest.erl \ wrap_log.erl EXTRA_DIST = $(MODULES) www EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t2/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t2/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test prepare-test:: $(AM_V_at)dd if=/dev/zero of=./docroot-test/1000.txt bs=1024 count=1000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/2000.txt bs=1024 count=2000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/3000.txt bs=1024 count=3000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/10000.txt bs=1024 count=10000 >/dev/null 2>&1 distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t2/jsontest.erl0000664000175000017500000000207212605311413013277 00000000000000-module(jsontest). -export([out/1, handler/3]). out(Arg) -> yaws_rpc:handler_session(Arg, {?MODULE, handler}). handler(_State, {call, subtract, Params}, _Session) -> {Minuend, Subtrahend} = case Params of {array, [M, S]} -> {M, S}; Obj -> {jsonrpc:s(Obj, "minuend"), jsonrpc:s(Obj, "subtrahend")} end, {true, undefined, undefined, {response, Minuend - Subtrahend}}; handler(_State, {notification, update, {array, [1,2,3,4,5]}}, _Session) -> false; handler(_State, {notification, foobar, undefined}, _Session) -> false; handler(_State, {call, sum, {array, Params}}, _Session) -> {true, undefined, undefined, {response, lists:sum(Params)}}; handler(_State, {notification, "notify_hello", {array, [7]}}, _Session) -> false; handler(_State, {call, get_data, undefined}, _Session) -> {true, undefined, undefined, {response, {array, ["hello", 5]}}}. yaws-2.0.2/test/t2/forwarded_for_test.erl0000664000175000017500000000045612605311413015314 00000000000000-module(forwarded_for_test). -export([out/1]). -include("yaws_api.hrl"). out(Arg) -> Fwd = yaws_api:headers_x_forwarded_for(Arg#arg.headers), {status, case string:tokens(Fwd, ", ") of ["192.168.1.1","192.168.1.2"] -> 200; _ -> 400 end}. yaws-2.0.2/test/t2/streamtest.erl0000664000175000017500000000240512605311413013621 00000000000000-module(streamtest). -export([out/1, streamer/1, close_streamer/2]). -include("yaws_api.hrl"). out(Arg) -> Sock = Arg#arg.clisock, Url = yaws_api:request_url(Arg), case lists:reverse(string:tokens(Url#url.path, "/")) of ["1"|_] -> Pid1 = spawn(?MODULE, streamer, [Sock]), {streamcontent_from_pid, "text/plain", Pid1}; ["2"|_] -> Msg = "closing the socket", Pid2 = spawn(?MODULE, close_streamer, [Sock, Msg]), [{header, {content_length, length(Msg)}}, {streamcontent_from_pid, "text/plain", Pid2}] end. streamer(Sock) -> receive {discard, YawsPid} -> yaws_api:stream_process_end(Sock, YawsPid); {ok, YawsPid} -> yaws_api:stream_process_deliver_final_chunk( Sock, ["this", " is", <<" an">>, <<" iolist">>] ), yaws_api:stream_process_end(Sock, YawsPid) end. close_streamer(Sock, Msg) -> receive {discard, YawsPid} -> yaws_api:stream_process_end(Sock, YawsPid); {ok, YawsPid} -> gen_tcp:send(Sock, Msg), timer:sleep(3000), gen_tcp:close(Sock), yaws_api:stream_process_end(closed, YawsPid) end. yaws-2.0.2/test/t2/posttest.erl0000664000175000017500000000647212605311413013323 00000000000000-module(posttest). -export([out/1]). -include("yaws.hrl"). -include("yaws_api.hrl"). out(Arg) -> Url = yaws_api:request_url(Arg), case Url#url.path of "/posttest/chunked/" ++ ExpectedSize -> TE = yaws:to_lower((Arg#arg.headers)#headers.transfer_encoding), if TE =:= "chunked" -> handle_post(list_to_integer(ExpectedSize), Arg); true -> Reason = io_lib:format("Expected a chunked transfer-encoding request\n~p", [Arg#arg.headers]), handle_post(0, Arg#arg{state={flush,500,Reason}}) end; "/posttest/" ++ ExpectedSize -> handle_post(list_to_integer(ExpectedSize), Arg); _ -> Reason = "unknown path: " ++ Url#url.path, handle_post(0, Arg#arg{state={flush,500,Reason}}) end. handle_post(_, #arg{clidata=Data, state={flush, HttpCode, Reason}}) -> %% Catch an error here but flush all remaining data. case Data of {partial, _} -> {get_more, undefined, {flush, HttpCode, Reason}}; _ -> [{status, HttpCode}, {html, Reason}] end; handle_post(ExpectedSize, #arg{clidata=Data, cont=undefined}=Arg) when is_binary(Data) -> %% This is not a partial request %% Expected: content_length =:= ExpectedSize AND %% content_length < partial_post_size. SC = get(sc), if size(Data) =:= ExpectedSize andalso size(Data) < SC#sconf.partial_post_size -> {status, 200}; true -> Reason = io_lib:format("Post data too big. " "Received: ~p bytes - Max: ~p bytes", [size(Data), SC#sconf.partial_post_size]), handle_post(ExpectedSize, Arg#arg{state={flush,500,Reason}}) end; handle_post(ExpectedSize, #arg{clidata={partial, Data}, cont=Cont}=Arg) when is_binary(Data) -> %% next Chunk of a partial request. if Cont =:= undefined -> %% First chunk {get_more, {cont, size(Data)}, undefined}; true -> {cont, Sz0} = Cont, Sz1 = Sz0 + size(Data), if Sz1 =< ExpectedSize -> {get_more, {cont, Sz1}, undefined}; true -> SC = get(sc), Reason = io_lib:format("Chunk too big. " "Received: ~p bytes - Max: ~p bytes", [size(Data), SC#sconf.partial_post_size]), handle_post(ExpectedSize, Arg#arg{state={flush,500,Reason}}) end end; handle_post(ExpectedSize, #arg{clidata=Data, cont=Cont}=Arg) when is_binary(Data) -> %% Last chunk of a partial request. {cont, Sz0} = Cont, Sz1 = Sz0 + size(Data), if Sz1 =:= ExpectedSize -> {status, 200}; true -> Reason = io_lib:format("Received data does not match " "the expected size. " "Received: ~p bytes - Expected: ~p bytes", [Sz1, ExpectedSize]), handle_post(ExpectedSize, Arg#arg{state={flush,500,Reason}}) end. yaws-2.0.2/test/t2/phptest.erl0000664000175000017500000000106412605311413013115 00000000000000-module(phptest). -export([out/1]). -include("yaws.hrl"). -include("yaws_api.hrl"). out(Arg) -> File = Arg#arg.fullpath, case filelib:is_file(File) of true -> case file:read_file(File) of {ok, Content} -> [{status, 200}, {content, "text/plain", Content}]; {error, Reason} -> [{status, 500}, {html, file:format_error(Reason)}] end; false -> Reason = "file not found: " ++ File, [{status, 500}, {html, Reason}] end. yaws-2.0.2/test/t2/appmod3.erl0000664000175000017500000000035412605311413012772 00000000000000-module(appmod3). -export([out/1]). out(Arg) -> Path = yaws_api:arg_server_path(Arg), Stack = get(appmod_stack), Options = [{header, {"X-AppMods", Stack++", appmod3["++Path++"]"}}], {page, {Options, "/1000.txt"}}. yaws-2.0.2/test/t2/flushtest.erl0000664000175000017500000000023112605311413013442 00000000000000-module(flushtest). -export([out/1]). -include("yaws.hrl"). -include("yaws_api.hrl"). out(_Arg) -> [{status, 200}, {html, "break"}, flush, break]. yaws-2.0.2/test/t2/app_test.erl0000664000175000017500000012050512605311413013247 00000000000000-module(app_test). -compile(export_all). -include_lib("ibrowse/include/ibrowse.hrl"). -include("tftest.hrl"). %% Way to invoke just one test start([F]) -> ?line {ok, _} = ibrowse:start_link(), apply(app_test, F, []), ibrowse:stop(). start() -> io:format("\n ==== MAIN TESTS ==== \n\n", []), ?line {ok, _} = ibrowse:start_link(), test_server_options(), test1(), test2(), test3(), test_appmod(), test_dispatchmod(), test_streamcontent(), sendfile_get(), test_json(), test_post(), test_flush(), test_te_trailer_and_extensions(), test_expires(), test_reentrant(), test_cgi_redirect(), test_php_handler(), test_arg_rewrite(), test_shaper(), test_sslaccept_timeout(), test_ssl_multipart_post(), test_throw(), test_too_many_headers(), test_index_files(), test_embedded_id_dir(), test_embedded_listen_ip(), test_chained_appmods(), test_cache_appmod(), test_multi_forwarded_for(), test_log_rotation(), test_exhtml(), ibrowse:stop(). test1() -> io:format("test1\n",[]), L = lists:seq(1, 100), SELF = self(), Pids = lists:map(fun(I) -> spawn(fun() -> slow_client(I, SELF) end) end, L), ?line ok = allow_connects(Pids, 5), ?line ok = collect_pids(Pids). collect_pids([]) -> ok; collect_pids(Pids) -> receive {Pid, done} -> collect_pids(lists:delete(Pid, Pids)) end. %% max 5 connectors at a time allow_connects([], _) -> io:format(" test1: all pids connected \n",[]); allow_connects(Pids, 0) -> receive {Pid, connected} -> allow_connects(lists:delete(Pid, Pids), 1) end; allow_connects(Pids, I) -> receive {Pid, allow} -> Pid ! allow, allow_connects(Pids, I-1); {Pid, connected} -> allow_connects(lists:delete(Pid, Pids), I+1) end. slow_client(I, Top) -> Top ! {self(), allow}, receive allow -> ok end, ?line {ok, C} = gen_tcp:connect(localhost, 8000, [{active, false}, {packet, http}]), Top ! {self(), connected}, ?line ok = gen_tcp:send(C, "GET /1000.txt HTTP/1.1\r\n" "Host: localhost:8000\r\n\r\n"), ?line {ok, Sz} = get_cont_len(C), ?line ok = inet:setopts(C, [binary,{packet, 0}]), read_loop(C, I, Sz), Top ! {self(), done}. read_loop(C, _I, Sz) when Sz - 200000 < 0 -> ?line ok = gen_tcp:close(C), ok; read_loop(C, I, Sz) -> ?line {ok, B} = gen_tcp:recv(C, 0), %%io:format("(I=~p Sz=~p) ", [I, size(B)]), timer:sleep(2), read_loop(C, I, Sz - size(B)). get_cont_len(C) -> ?line {value, {http_header, _,_,_, LenStr}} = lists:keysearch('Content-Length', 3, tftest:get_headers(C)), {ok, erlang:list_to_integer(LenStr)}. test2() -> io:format("test2\n",[]), blkget(10). blkget(0) -> ok; blkget(I) -> spawn(fun() -> {ok, C} = gen_tcp:connect(localhost, 8000, [{active, false}]), gen_tcp:send(C, "GET /2000.txt HTTP/1.1\r\n" "Host: localhost:8000\r\n\r\n"), gen_tcp:recv(C, 200), timer:sleep(5000), exit(normal) end), blkget(I-1). test3() -> io:format("test3\n",[]), ?line {ok, "200", _Headers, []} = ibrowse:send_req("http://localhost:8000", [], head), ok. test_server_options() -> io:format("server_options_test\n",[]), {ok, S} = gen_tcp:connect("localhost", 8000, [{packet, raw}, list, {active, false}]), ok = gen_tcp:send(S, "OPTIONS * HTTP/1.1\r\nHost: localhost\r\n\r\n"), inet:setopts(S, [{packet, http}]), ?line ok = server_options_recv(S), gen_tcp:close(S). server_options_recv(S) -> do_server_options_recv(S, []). server_options_recv(_S, [http_eoh|_]) -> ok; server_options_recv(S, [{http_response,{1,1},200,"OK"}|_]=Hdrs) -> do_server_options_recv(S, Hdrs); server_options_recv(S, [{http_header,_,'Server',_,_}|_]=Hdrs) -> do_server_options_recv(S, Hdrs); server_options_recv(S, [{http_header,_,'Allow',_,"GET, HEAD, OPTIONS, PUT, POST, DELETE"}|_]=Hdrs) -> do_server_options_recv(S, Hdrs); server_options_recv(S, [{http_header,_,'Content-Length',_,"0"}|_]=Hdrs) -> do_server_options_recv(S, Hdrs); server_options_recv(S, [{http_header,_,'Date',_,_}|_]=Hdrs) -> do_server_options_recv(S, Hdrs); server_options_recv(_S, [Hdr|_Hdrs]) -> io:format("unexpected server options HTTP header: ~p~n", [Hdr]), error. do_server_options_recv(S, Hdrs) -> {ok, Hdr} = gen_tcp:recv(S, 0, 5000), server_options_recv(S, [Hdr|Hdrs]). -define(SENDFILE_GET_TIMEOUT, 120000). sendfile_get() -> io:format("sendfile_get\n",[]), L = lists:seq(1, 5), SELF = self(), K1 = lists:map( fun(_) -> spawn(fun() -> ?line {ok, "200", _Headers, _} = ibrowse:send_req( "http://localhost:8000/1000.txt", [], get, [], [], ?SENDFILE_GET_TIMEOUT), SELF ! {self(), k1, done} end) end, L), K2 = lists:map( fun(_) -> spawn(fun() -> ?line {ok, "200", _Headers, _} = ibrowse:send_req( "http://localhost:8000/2000.txt", [], get, [], [], ?SENDFILE_GET_TIMEOUT), SELF ! {self(), k2, done} end) end, L), K3 = lists:map( fun(_) -> spawn(fun() -> ?line {ok, "200", _Headers, _} = ibrowse:send_req( "http://localhost:8000/3000.txt", [], get, [], [], ?SENDFILE_GET_TIMEOUT), SELF ! {self(), k3, done} end) end, L), collect(K1, 1, k1), collect(K2, 1, k2), collect(K3, 1, k3), io:format("\n",[]), ok. collect([], _, _) -> ok; collect(L, Count, Tag) -> receive {Pid, Tag, done} -> io:format("(~p ~p)", [Tag, Count]), collect(lists:delete(Pid, L), Count+1, Tag) after ?SENDFILE_GET_TIMEOUT -> io:format("TIMEOUT ~p\n~p~n",[process_info(self()), L]), ?line exit(timeout) end. -define(APPMOD_HEADER, "Appmod-Called"). test_appmod() -> io:format("appmod_test\n",[]), Uri1 = "http://localhost:8002/", ?line {ok, "200", Headers1, _} = ibrowse:send_req(Uri1, [], get), ?line "true" = proplists:get_value(?APPMOD_HEADER, Headers1), Uri2 = "http://localhost:8003/", ?line {ok, "200", Headers2, _} = ibrowse:send_req(Uri2, [], get), ?line "true" = proplists:get_value(?APPMOD_HEADER, Headers2), Uri3 = "http://localhost:8003/icons/layout.gif", ?line {ok, "200", Headers3, _} = ibrowse:send_req(Uri3, [], get), ?line false = proplists:get_value(?APPMOD_HEADER, Headers3, false), Uri4 = "http://localhost:8004/non_root_appmod", ?line {ok, "200", Headers4, _} = ibrowse:send_req(Uri4, [], get), ?line "true" = proplists:get_value(?APPMOD_HEADER, Headers4), ok. test_dispatchmod() -> io:format("dispatchmod test\n", []), Uri1 = "http://localhost:8011/done", ?line {ok, "204", Headers1, _} = ibrowse:send_req(Uri1, [], get), ?line "true" = proplists:get_value("X-DispatchMod", Headers1), Uri2 = "http://localhost:8011/closed", ?line {ok, "200", Headers2, _} = ibrowse:send_req(Uri2, [], get), ?line "close" = proplists:get_value("Connection", Headers2), Uri3 = "http://localhost:8011/index.yaws", ?line {ok, "200", _, _} = ibrowse:send_req(Uri3, [], get), ok. test_streamcontent() -> io:format("streamcontent_test\n",[]), Uri1 = "http://localhost:8000/streamtest/1", ?line {ok, "200", Headers1, Body1} = ibrowse:send_req(Uri1, [], get), ?line "chunked" = proplists:get_value("Transfer-Encoding", Headers1), ?line Body1 = "this is an iolist", %% The following test attempts to ensure that Yaws doesn't report the %% following problem due to the application closing the socket and then %% handing it back to Yaws via stream_process_end. %% %% =ERROR REPORT==== 12-May-2010::00:27:05 === %% Yaws process died: {{badmatch,{error,einval}}, %% [{yaws,setopts,3}, %% {yaws,http_recv_request,2}, %% {yaws,do_http_get_headers,2}, %% {yaws,http_get_headers,2}, %% {yaws_server,aloop,3}, %% {yaws_server,acceptor0,2}, %% {proc_lib,init_p_do_apply,3}]} %% %% The test uses plain sockets because closing the remote end makes %% ibrowse unhappy. Unfortunately the only way to currently check that %% the above message doesn't appear is to turn on traffic tracing in %% yaws.conf and then visually check the file logs/report.log. %% Path = "/streamtest/2", {ok, Sock} = gen_tcp:connect("localhost", 8000, [binary, {active, false}]), gen_tcp:send(Sock, "GET " ++ Path ++ " HTTP/1.1\r\nHost: localhost\r\n\r\n"), inet:setopts(Sock, [{packet, http}]), {ok, Len} = recv_hdrs(Sock), inet:setopts(Sock, [{packet, raw}, {active, false}]), {ok, <<"closing the socket">>} = gen_tcp:recv(Sock, Len), timer:sleep(10000), gen_tcp:close(Sock), ok. -define(JSON_URI, "http://localhost:8005/jsontest"). test_json() -> io:format("json_test\n",[]), io:format(" param array1\n", []), ?line ok = do_json({struct, [{"jsonrpc", "2.0"}, {"method", "subtract"}, {"params", {array, [42, 23]}}, {"id", 1}]}, {struct, [{"jsonrpc", "2.0"}, {"result", 19}, {"id", 1}]}), io:format(" param array2\n", []), ?line ok = do_json({struct, [{"jsonrpc", "2.0"}, {"method", "subtract"}, {"params", {array, [23, 42]}}, {"id", 2}]}, {struct, [{"jsonrpc", "2.0"}, {"result", -19}, {"id", 2}]}), inets:start(), io:format(" encode/decode\n", []), ?line {ok,{response,[19]}} = jsonrpc:call(?JSON_URI, [], {call, "subtract", [42, 23]}), UStr = "{ \"origfilename\":\"Acronyms \\u2013 April 2014.pptx\" }", ?line {ok, {struct,[{"origfilename",US}]}} = json2:decode_string(UStr), ?line iolist_to_binary(US), % must not cause a badarg exception io:format(" param obj1\n", []), ?line ok = do_json({struct, [{"jsonrpc", "2.0"}, {"method", "subtract"}, {"params", {struct, [{"subtrahend", 23}, {"minuend", 42}]}}, {"id", 3}]}, {struct, [{"jsonrpc", "2.0"}, {"result", 19}, {"id", 3}]}), io:format(" param obj2\n", []), ?line ok = do_json({struct, [{"jsonrpc", "2.0"}, {"method", "subtract"}, {"params", {struct, [{"minuend", 42}, {"subtrahend", 23}]}}, {"id", 4}]}, {struct, [{"jsonrpc", "2.0"}, {"result", 19}, {"id", 4}]}), io:format(" notif1\n", []), ?line ok = do_json({struct, [{"jsonrpc", "2.0"}, {"method", "update"}, {"params", {array, [1,2,3,4,5]}}]}, notification), io:format(" notif2\n", []), ?line ok = do_json({struct, [{"jsonrpc", "2.0"}, {"method", "foobar"}]}, notification), io:format(" missing method\n", []), ?line ok = do_json({struct, [{"jsonrpc", "2.0"}, {"method", "foobar"}, {"id", "1"}]}, {struct, [{"jsonrpc", "2.0"}, {"id", "1"}, {"error", {struct, [{"code", -32601}, {"message", "method not found"}]} }]}), io:format(" invalid json\n", []), InvalidJson = "{\"jsonrpc\": \"2.0\", \"method\": \"foobar," "\"params\": \"bar\", \"baz]", ?line ok = do_json(InvalidJson, {struct, [{"jsonrpc", "2.0"}, {"id", null}, {"error", {struct, [{"code", -32700}, {"message", "parse error"}]} }]}, no_encode), io:format(" invalid req1\n", []), InvalidReq1 = "{\"jsonrpc\": \"2.0\", \"method\": 1, \"params\": \"bar\"}", ?line ok = do_json(InvalidReq1, {struct, [{"jsonrpc", "2.0"}, {"id", null}, {"error", {struct, [{"code", -32600}, {"message", "invalid request"}]} }]}, no_encode), io:format(" invalid params\n", []), InvalidReq2 = "{\"jsonrpc\": \"2.0\", \"method\": \"x\"," "\"params\": \"bar\"}", ?line ok = do_json(InvalidReq2, {struct, [{"jsonrpc", "2.0"}, {"id", null}, {"error", {struct, [{"code", -32602}, {"message", "invalid params"}]} }]}, no_encode), io:format(" invalid batch json\n", []), InvalidJsonBatch = "[ {\"jsonrpc\": \"2.0\", \"method\": \"sum\"," "\"params\": [1,2,4],\"id\": \"1\"},{\"jsonrpc\": \"2.0\", \"method\" ]", ?line ok = do_json(InvalidJsonBatch, {struct, [{"jsonrpc", "2.0"}, {"id", null}, {"error", {struct, [{"code", -32700}, {"message", "parse error"}]} }]}, no_encode), io:format(" empty batch\n", []), EmptyBatch = "[]", ?line ok = do_json(EmptyBatch, {struct, [{"jsonrpc", "2.0"}, {"id", null}, {"error", {struct, [{"code", -32600}, {"message", "invalid request"}]} }]}, no_encode), io:format(" invalid batch1\n", []), BogusBatch1 = "[1]", ?line ok = do_json(BogusBatch1, {array, [{struct, [{"jsonrpc", "2.0"}, {"id", null}, {"error", {struct, [{"code", -32600}, {"message", "invalid request"}]} }]}]}, no_encode), io:format(" invalid batch2\n", []), BogusBatch2 = "[1,2,3]", ?line ok = do_json(BogusBatch2, {array, [{struct, [{"jsonrpc", "2.0"}, {"id", null}, {"error", {struct, [{"code", -32600}, {"message", "invalid request"}]} }]}, {struct, [{"jsonrpc", "2.0"}, {"id", null}, {"error", {struct, [{"code", -32600}, {"message", "invalid request"}]} }]}, {struct, [{"jsonrpc", "2.0"}, {"id", null}, {"error", {struct, [{"code", -32600}, {"message", "invalid request"}]} }]}]}, no_encode), io:format(" mixed batch\n", []), MixedBatch = " [{\"jsonrpc\":\"2.0\",\"method\":\"sum\",\"params\": [1,2,4], \"id\": \"1\"}, {\"jsonrpc\":\"2.0\",\"method\":\"notify_hello\", \"params\": [7]}, {\"jsonrpc\":\"2.0\",\"method\":\"subtract\",\"params\":[42,23], \"id\":\"2\"}, {\"foo\": \"boo\"}, {\"jsonrpc\":\"2.0\",\"method\":\"foo.get\", \"params\":{\"name\": \"myself\"}, \"id\": \"5\"}, {\"jsonrpc\": \"2.0\", \"method\": \"get_data\", \"id\": \"9\"}]", ?line ok = do_json(MixedBatch, {array, [{struct,[{"jsonrpc","2.0"}, {"result",7}, {"id","1"}]}, {struct,[{"jsonrpc","2.0"}, {"result",19},{"id","2"}]}, {struct,[{"jsonrpc","2.0"}, {"error", {struct,[{"code",-32600}, {"message","invalid request"}]}}, {"id",null}]}, {struct,[{"jsonrpc","2.0"}, {"error", {struct,[{"code",-32601}, {"message","method not found"}]}}, {"id","5"}]}, {struct,[{"jsonrpc","2.0"}, {"result",{array,["hello",5]}}, {"id","9"}]}]}, no_encode), io:format(" all-notification batch\n", []), NotifBatch = "[ {\"jsonrpc\": \"2.0\", \"method\": \"notify_sum\", \"params\": [1,2,4]}, {\"jsonrpc\": \"2.0\", \"method\": \"notify_hello\", \"params\": [7]}]", ?line ok = do_json(NotifBatch, notification, no_encode), ok. do_json(Req, Expected) -> do_json(Req, Expected, encode). do_json(Req, notification, NeedEncode) -> ?line {ok, "200", Headers, Body} = json_send(Req, NeedEncode), ?line "application/json" = proplists:get_value("Content-Type", Headers), ?line [] = Body, ok; do_json(Req, {struct, _}=Expected, NeedEncode) -> ?line {ok, "200", Headers, Body} = json_send(Req, NeedEncode), ?line "application/json" = proplists:get_value("Content-Type", Headers), check_json(Expected, Body, true); do_json(Req, {array, Array}, NeedEncode) -> ?line {ok, "200", Headers, Body} = json_send(Req, NeedEncode), ?line "application/json" = proplists:get_value("Content-Type", Headers), ?line {ok, {array, GotArray}} = json2:decode_string(Body), lists:map(fun({Obj, Got}) -> ?line ok = check_json(Obj, Got, false) end, lists:zip(Array, GotArray)), ok. check_json({struct, _}=Exp, Body, true) -> ?line {ok, DecodedBody} = json2:decode_string(Body), check_json(Exp, DecodedBody); check_json({struct, _}=Exp, Body, false) -> check_json(Exp, Body). check_json({struct, Members}, DecodedBody) -> lists:foreach(fun({Key, Val}) -> ?line Val = jsonrpc:s(DecodedBody, Key) end, Members), ok. json_send(Req) -> json_send(Req, encode). json_send(Req, encode) -> json_send(json2:encode(Req), no_encode); json_send(Req, no_encode) -> Uri = ?JSON_URI, ReqHdrs = [{content_type, "application/json"}], ibrowse:send_req(Uri, ReqHdrs, post, Req). recv_hdrs(Sock) -> recv_hdrs(Sock, 0). recv_hdrs(Sock, Len) -> inet:setopts(Sock, [{active, once}]), receive {http, Sock, http_eoh} -> {ok, Len}; {http, Sock, {http_error, Error}} -> {error, Error}; {http, Sock, {http_header, _, 'Content-Length', _, LenStr}} -> recv_hdrs(Sock, erlang:list_to_integer(LenStr)); {http, Sock, {http_header, _, _, _, _}} -> recv_hdrs(Sock, Len); {http, Sock, {http_response, _, 200, "OK"}} -> recv_hdrs(Sock, Len); Other -> {error, {"unexpected message", Other}} end. %% partial_post_size = 2048000 test_post() -> io:format("post_test\n",[]), small_post(), large_post(), small_chunked_post(), large_chunked_post(), ok. small_post() -> io:format(" small post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/1000.txt"), Sz = size(Bin), Uri = "http://localhost:8006/posttest/" ++ erlang:integer_to_list(Sz), Hdrs = [{content_length, Sz}, {content_type, "binary/octet-stream"}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Hdrs, post, Bin, []), ok. large_post() -> io:format(" large post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/10000.txt"), Sz = size(Bin), Uri = "http://localhost:8006/posttest/" ++ erlang:integer_to_list(Sz), Hdrs = [{content_length, Sz}, {content_type, "binary/octet-stream"}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Hdrs, post, Bin, []), ok. small_chunked_post() -> io:format(" small chunked post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/3000.txt"), Sz = size(Bin), Uri = "http://localhost:8006/posttest/chunked/" ++ erlang:integer_to_list(Sz), Hdrs = [{content_type, "binary/octet-stream"}], Opts = [{transfer_encoding, {chunked, 1000*1000}}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Hdrs, post, Bin, Opts), ok. large_chunked_post() -> io:format(" large chunked post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/10000.txt"), Sz = size(Bin), Uri = "http://localhost:8006/posttest/chunked/" ++ erlang:integer_to_list(Sz), Hdrs = [{content_type, "binary/octet-stream"}], %% size of chunk _IS_NOT_ a multiple of partial_post_size Opts1 = [{transfer_encoding, {chunked, 4000*1000}}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Hdrs, post, Bin, Opts1), %% size of chunk _IS_ a multiple of partial_post_size Opts2 = [{transfer_encoding, {chunked, 4000*1024}}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Hdrs, post, Bin, Opts2), ok. test_flush() -> io:format("flush_test\n",[]), flush_small_post(), flush_large_post(), flush_chunked_post(), flush_small_get(), flush_large_get(), flush_chunked_get(), ok. flush_small_post() -> io:format(" flush small post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/1000.txt"), Sz = size(Bin), Uri1 = "http://localhost:8006/flushtest/" ++ erlang:integer_to_list(Sz), Uri2 = "http://localhost:8006/hello.txt", Hdrs = [{content_length, Sz}, {content_type, "binary/octet-stream"}], {ok, ConnPid} = ibrowse:spawn_worker_process("localhost", 8006), ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri1, Hdrs, post, Bin, []), ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri2, [], get, [], []), ibrowse:stop_worker_process(ConnPid), ok. flush_large_post() -> io:format(" flush large post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/10000.txt"), Sz = size(Bin), Uri1 = "http://localhost:8006/flushtest/" ++ erlang:integer_to_list(Sz), Uri2 = "http://localhost:8006/hello.txt", Hdrs = [{content_length, Sz}, {content_type, "binary/octet-stream"}], {ok, ConnPid} = ibrowse:spawn_worker_process("localhost", 8006), ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri1, Hdrs, post, Bin, []), ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri2, [], get, [], []), ibrowse:stop_worker_process(ConnPid), ok. flush_chunked_post() -> io:format(" flush chunked post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/10000.txt"), Sz = size(Bin), Uri1 = "http://localhost:8006/flushtest/chunked/" ++ erlang:integer_to_list(Sz), Uri2 = "http://localhost:8006/hello.txt", Hdrs = [{content_type, "binary/octet-stream"}], Opts = [{transfer_encoding, {chunked, 4000*1000}}], {ok, ConnPid} = ibrowse:spawn_worker_process("localhost", 8006), ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri1, Hdrs, post, Bin, Opts), ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri2, [], get, [], []), ibrowse:stop_worker_process(ConnPid), ok. flush_small_get() -> io:format(" flush small get\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/1000.txt"), Sz = size(Bin), Uri = "http://localhost:8006/hello.txt", Hdrs = [{content_length, Sz}, {content_type, "binary/octet-stream"}], {ok, ConnPid} = ibrowse:spawn_worker_process("localhost", 8006), ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri, Hdrs, get, Bin, []), ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri, [], get, [], []), ibrowse:stop_worker_process(ConnPid), ok. flush_large_get() -> io:format(" flush large get\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/10000.txt"), Sz = size(Bin), Uri = "http://localhost:8006/hello.txt", Hdrs = [{content_length, Sz}, {content_type, "binary/octet-stream"}], {ok, ConnPid} = ibrowse:spawn_worker_process("localhost", 8006), ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri, Hdrs, get, Bin, []), ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri, [], get, [], []), ibrowse:stop_worker_process(ConnPid), ok. flush_chunked_get() -> io:format(" flush chunked post\n",[]), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/10000.txt"), Uri = "http://localhost:8006/hello.txt", Hdrs = [{content_type, "binary/octet-stream"}], Opts = [{transfer_encoding, {chunked, 4000*1000}}], {ok, ConnPid} = ibrowse:spawn_worker_process("localhost", 8006), ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Hdrs, get, Bin, Opts), ?line {ok, "200", _, _} = ibrowse:send_req(Uri, [], get, [], []), ibrowse:stop_worker_process(ConnPid), ok. test_te_trailer_and_extensions() -> io:format("te_trailer_and_extensions_test\n",[]), {ok, Sock} = gen_tcp:connect("localhost", 8006, [binary, {active, false}]), Data = ["This is the data in the first chunk\n", "and this is the second one\n", "con", "sequence"], Path = "/posttest/chunked/" ++ erlang:integer_to_list(length(lists:flatten(Data))), ?line gen_tcp:send(Sock, "POST "++Path++" HTTP/1.1\r\n" "Host: localhost\r\n" "Trailer: Content-Type\r\n" "Trailer: Extra-Headers-WooHoo\r\n" "Transfer-Encoding: Chunked\r\n\r\n"), Body = lists:flatten([[erlang:integer_to_list(length(X), 16),"; foo=bar\r\n", X,"\r\n"] || X <- Data]), ?line gen_tcp:send(Sock, Body), ?line gen_tcp:send(Sock, "0\r\n" "Extra-Headers-WooHoo: something\r\n" "Content-Type: text/plain\r\n\r\n"), inet:setopts(Sock, [{packet, http}]), ?line {ok, _Len} = recv_hdrs(Sock), gen_tcp:close(Sock), ok. test_expires() -> io:format("expires_test\n", []), Uri1 = "http://localhost:8006/hello.txt", ?line {ok, "200", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), %% Test "text/plain" rule %% - Retrieve max-age value to test Expires header ?line CCtrl1 = proplists:get_value("Cache-Control", Hdrs1), ?line {match, ["2592000"]} = re:run(CCtrl1, "max-age=(\\d+)", [{capture,all_but_first,list}]), %% - Convert Date and Expires into datetime() ?line Date = proplists:get_value("Date", Hdrs1), ?line Expires = proplists:get_value("Expires", Hdrs1), Date_DT = httpd_util:convert_request_date(Date), Expires_DT = httpd_util:convert_request_date(Expires), %% - Check if Expires value is equal to "Date + max-age" Val1 = calendar:datetime_to_gregorian_seconds(Date_DT) + 2592000, Val2 = calendar:datetime_to_gregorian_seconds(Expires_DT), ?line Val1 = Val2, %% Test "*/*" rule Uri2 = "http://localhost:8006/", ?line {ok, "200", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line CCtrl2 = proplists:get_value("Cache-Control", Hdrs2), ?line {match, ["0"]} = re:run(CCtrl2, "max-age=(\\d+)", [{capture,all_but_first,list}]), %% Test "image/*" rule Uri3 = "http://localhost:8006/yaws_head.gif", ?line {ok, "200", Hdrs3, _} = ibrowse:send_req(Uri3, [], get), ?line CCtrl3 = proplists:get_value("Cache-Control", Hdrs3), ?line {match, ["2592000"]} = re:run(CCtrl3, "max-age=(\\d+)", [{capture,all_but_first,list}]), ok. test_reentrant() -> io:format("reentrant_test\n", []), reentrant_test_status(), reentrant_test_delayed_headers(), ok. reentrant_test_status() -> io:format(" status code\n", []), Uri = "http://localhost:8006/reentranttest/status", ?line {ok, "201", _, _} = ibrowse:send_req(Uri, [], post, <<"blob">>, []), ok. reentrant_test_delayed_headers() -> io:format(" delayed headers\n", []), Uri = "http://localhost:8006/reentranttest/delayed_headers", ?line {ok, "200", Hdrs, _} = ibrowse:send_req(Uri, [], get), ?line "no-cache" = proplists:get_value("Cache-Control", Hdrs), ?line "static-tag" = proplists:get_value("Etag", Hdrs), ?line "true" = proplists:get_value("X-Delayed-Header", Hdrs), ok. test_cgi_redirect() -> io:format("cgi_redirect_test\n", []), Uri = "http://localhost:8008/cgi-bin/redirect_test.cgi", ?line {ok, "302", Hdrs, _} = ibrowse:send_req(Uri, [], get), ?line true = lists:any(fun({"Location", _}) -> true; (_) -> false end, Hdrs), ok. test_php_handler() -> io:format("php_handler_test\n", []), Uri = "http://localhost:8006/test.php", {ok, Binary} = file:read_file(?srcdir ++ "/www/test.php"), Content = binary_to_list(Binary), ?line {ok, "200", _, Content} = ibrowse:send_req(Uri, [], get), ok. test_arg_rewrite() -> io:format("arg_rewrite_test\n", []), arg_rewrite_test_rewrite(), arg_rewrite_test_redirect(), arg_rewrite_test_response(), ok. arg_rewrite_test_rewrite() -> io:format(" rewrite\n", []), Uri = "http://localhost:8006/rewrite", ?line {ok, "200", Hdrs, _} = ibrowse:send_req(Uri, [], get), ?line "text/plain" = split_content_type(Hdrs), {ok, FI} = file:read_file_info(?srcdir ++ "/www/hello.txt"), Etag = yaws:make_etag(FI), ?line Etag = proplists:get_value("Etag", Hdrs), ok. arg_rewrite_test_redirect() -> io:format(" redirect\n", []), Uri = "http://localhost:8006/redirect", ?line {ok, "301", Hdrs, _} = ibrowse:send_req(Uri, [], get), ?line "http://www.yakaz.com" = proplists:get_value("Location", Hdrs), ok. arg_rewrite_test_response() -> io:format(" response\n", []), Uri = "http://localhost:8006/response", ?line {ok, "200", Hdrs, Content} = ibrowse:send_req(Uri, [], get), ?line "text/plain" = split_content_type(Hdrs), ?line "Goodbye, Cruel World!" = Content, ok. %% split content type away from any charset info split_content_type(Hdrs) -> hd(string:tokens(proplists:get_value("Content-Type", Hdrs), " ;")). test_shaper() -> io:format("shaper_test\n", []), Uri = "http://localhost:8007/", ?line {ok, "200", _, _} = ibrowse:send_req(Uri, [], get), ?line {ok, "200", _, _} = ibrowse:send_req(Uri, [], get), ?line {ok, "200", _, _} = ibrowse:send_req(Uri, [], get), ?line {ok, "503", _, _} = ibrowse:send_req(Uri, [], get), ok. test_sslaccept_timeout() -> case erlang:system_info(version) of "5.9.3" -> io:format("sslaccept_tout_test (skipping due to R15B03 bug)\n", []); _ -> io:format("sslaccept_tout_test\n", []), {ok, Sock} = gen_tcp:connect("localhost", 8443, [binary, {active, true}]), ?line ok = receive {tcp_closed, Sock} -> ok after %% keepalive_timeout is set to 10 secs. So, wait 15 secs %% before returning an error 15000 -> error end, gen_tcp:close(Sock) end, ok. test_ssl_multipart_post() -> io:format("ssl_multipart_post_test\n", []), ok = application:start(crypto), ok = application:start(asn1), ok = application:start(public_key), ok = application:start(ssl), Boundary = "----------------------------3e9876546ecf\r\n", {ok, Bin0} = file:read_file(?builddir ++ "/docroot-test/1000.txt"), Data = list_to_binary([Boundary, Bin0]), Size = size(Data), Headers = [ {'Content-Type', "multipart/form-data; Boundary=" ++ Boundary}, {'Content-Length', Size} ], Uri = "https://localhost:8443/test_upload_ssl.yaws", Options = [{is_ssl, true}, {ssl_options, [{verify, 0}]}], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, Headers, post, Data, Options), ok = application:stop(ssl), ok = application:stop(public_key), ok = application:stop(asn1), ok = application:stop(crypto), ok. test_throw() -> io:format("throw test\n", []), Uri = "http://localhost:8009/", ?line {ok, "500", _, _} = ibrowse:send_req(Uri, [], get), ok. test_too_many_headers() -> io:format("too many request headers test\n", []), Uri = "http://localhost:8009/", Hdrs = [{link, "; rel=\"stylesheet\"; title=\"compact\""} || _ <- lists:seq(0, 1001)], ?line {ok, "431", _, _} = ibrowse:send_req(Uri, Hdrs, get), ok. test_index_files() -> io:format("index_files test\n", []), ?line {ok, Bin} = file:read_file(?srcdir ++ "/../..//www/testdir/index.html"), Content = binary_to_list(Bin), %% "/" should be redirected to "/testdir", then to "/testdir/" and finally %% get "/testdir/index.html" Uri0 = "http://localhost:8010/", ?line {ok, "302", Hdrs1, _} = ibrowse:send_req(Uri0, [], get), ?line Uri1 = proplists:get_value("Location", Hdrs1), ?line "http://localhost:8010/testdir" = Uri1, ?line {ok, "302", Hdrs2, _} = ibrowse:send_req(Uri1, [], get), ?line Uri2 = proplists:get_value("Location", Hdrs2), ?line "http://localhost:8010/testdir/" = Uri2, ?line {ok, "200", _, Content} = ibrowse:send_req(Uri2, [], get), %% Do the same thing but with a query-string Uri3 = "http://localhost:8010/?a=1&b=2", ?line {ok, "302", Hdrs3, _} = ibrowse:send_req(Uri3, [], get), ?line Uri4 = proplists:get_value("Location", Hdrs3), ?line "http://localhost:8010/testdir?a=1&b=2" = Uri4, ?line {ok, "302", Hdrs4, _} = ibrowse:send_req(Uri4, [], get), ?line Uri5 = proplists:get_value("Location", Hdrs4), ?line "http://localhost:8010/testdir/?a=1&b=2" = Uri5, ?line {ok, "200", _, Content} = ibrowse:send_req(Uri5, [], get), ok. test_embedded_id_dir() -> io:format("test_embedded_id_dir\n", []), Id = "id_dir_test", GconfList = [{id, Id}, {logdir, "./logs"}, {ebin_dir, ["./ebin"]}], Docroot = yaws:tmpdir(), SconfList = [{port, 0}, {servername, Id}, {listen, {127,0,0,1}}, {docroot, Docroot}], {ok, _SCList, _GC, _ChildSpecs} = yaws_api:embedded_start_conf( Docroot, SconfList, GconfList, Id), try {ok, {file_info, _, directory, read_write, _, _, _, _, _, _, _, _, _, _}} = file:read_file_info(yaws:id_dir(Id)), ok after ok = file:del_dir(yaws:id_dir(Id)) end. test_embedded_listen_ip() -> %% make sure we can specify a listen address as either %% a list or a tuple lists:map(fun(IP) -> DocRoot = ".", Id = "embedded_listen", SConf = [{servername, "embedded_listen:8000"}, {docroot, DocRoot}, {listen, IP}, {port, 0}, {appmods,[{"/", ?MODULE}]}], GConf = [{id, Id}], ok = yaws:start_embedded(DocRoot, SConf, GConf, Id), yaws:stop() end, [{0,0,0,0}, "0.0.0.0"]). test_chained_appmods() -> io:format("test_chained_appmods\n", []), {ok, Bin} = file:read_file(?builddir ++ "/docroot-test/1000.txt"), Content = binary_to_list(Bin), Uri = "http://localhost:8012/", ?line {ok, "200", Hdrs, Content} = ibrowse:send_req(Uri, [], get), ?line "appmod1[/], appmod2[/appmod2], appmod1[/appmod1], appmod3[/1000.txt]" = proplists:get_value("X-AppMods", Hdrs), ok. test_cache_appmod() -> io:format("test_cache_appmod\n", []), Uri1 = "http://localhost:8013/index.yaws?no-cache=1", Uri2 = "http://localhost:8013/index.yaws", %% call cache_appmod_test and disable page cache ?line {ok, "200", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), ?line "cache_appmod_test" = proplists:get_value("X-Appmod", Hdrs1), %% check that index.yaws is not cached ?line {ok, "200", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line "cache_appmod_test" = proplists:get_value("X-Appmod", Hdrs2), %% retrieve index.yaws from the cache, so cache_appmod_test is not called ?line {ok, "200", Hdrs3, _} = ibrowse:send_req(Uri2, [], get), ?line undefined = proplists:get_value("X-Appmod", Hdrs3), ok. test_multi_forwarded_for() -> io:format("test_multi_forwarded_for\n", []), %% apparently ibrowse can't handle sending two separate headers with %% the same name but different values, which is needed for this test ?line {ok, S} = gen_tcp:connect(localhost, 8014, [{active,false}, {packet,http}]), ok = gen_tcp:send(S, ["GET / HTTP/1.1\r\nHost: localhost\r\n" "X-Forwarded-For: 192.168.1.1\r\n", "X-Forwarded-For: 192.168.1.2\r\n\r\n"]), ?line ok = check_forwarded_for(S), ok. check_forwarded_for(S) -> inet:setopts(S, [{active,once}]), receive {http, S, {http_response, _, Code, _}} -> gen_tcp:close(S), case Code of 200 -> ok; _ -> Code end end. test_log_rotation() -> io:format("test_log_rotation\n", []), %% Write 1M of data in .access and .auth log to check the log rotation ?line {ok, Fd1} = file:open(?builddir ++ "/logs/localhost:8000.access", [write]), ?line ok = file:write(Fd1, lists:duplicate(1000001, $a)), file:close(Fd1), file:sync(Fd1), ?line {ok, Fd2} = file:open(?builddir ++ "/logs/localhost:8000.auth", [write]), ?line ok = file:write(Fd2, lists:duplicate(1000001, $a)), file:close(Fd2), file:sync(Fd2), ?line {ok, "200", _, _} = ibrowse:send_req("http://localhost:8000/wrap_log", [], get), timer:sleep(500), ?line {ok, _} = file:read_file_info(?builddir ++ "/logs/localhost:8000.access.old"), ?line {ok, _} = file:read_file_info(?builddir ++ "/logs/localhost:8000.auth.old"), ?line {ok, _} = file:read_file_info(?builddir ++ "/logs/localhost:8000.access"), ?line {ok, _} = file:read_file_info(?builddir ++ "/logs/localhost:8000.auth"), ok. test_exhtml() -> io:format("test_exhtml\n", []), %% See github issue #216 ?line {ok, "200", _, Body} = ibrowse:send_req("http://localhost:8000/exhtml.yaws", [], get), Expected = "

\n bar\n

\n", Body = Expected, ok. %% used for appmod tests %% out(_A) -> %% add our special header to mark that we were here [{status, 200}, {header, {?APPMOD_HEADER, "true"}}]. yaws-2.0.2/test/t2/appmod1.erl0000664000175000017500000000052612605311413012771 00000000000000-module(appmod1). -export([out/1]). out(Arg) -> case yaws_api:arg_server_path(Arg) of "/" -> put(appmod_stack, "appmod1[/]"), {page, "/appmod2"}; Path -> Stack = get(appmod_stack), put(appmod_stack, Stack++", appmod1["++Path++"]"), {page, "/1000.txt"} end. yaws-2.0.2/test/t2/cache_appmod_test.erl0000664000175000017500000000060712605311413015072 00000000000000-module(cache_appmod_test). -export([out/1]). -include("yaws_api.hrl"). out(Arg) -> {abs_path, Path} = (Arg#arg.req)#http_request.path, Opts0 = case yaws_api:queryvar(Arg, "no-cache") of {ok, "1"} -> [{disable_cache, true}]; _ -> [] end, Opts1 = [{header, {"X-Appmod", "cache_appmod_test"}}|Opts0], {page, {Opts1, Path}}. yaws-2.0.2/test/t2/www/0000775000175000017500000000000012605311413011625 500000000000000yaws-2.0.2/test/t2/www/test.php0000664000175000017500000000003412605311413013232 00000000000000 yaws-2.0.2/test/t2/www/cgi-bin/0000775000175000017500000000000012605311413013135 500000000000000yaws-2.0.2/test/t2/www/cgi-bin/redirect_test.cgi0000775000175000017500000000037512605311413016411 00000000000000#!/bin/sh # # Used to verify that Yaws augments the client response with # a 302 status code as required by the CGI 1.1 spec when only # a Location header is returned without a status code. # echo 'Location: http://localhost:1234/redirect' echo exit 0 yaws-2.0.2/test/t2/www/yaws_head.gif0000664000175000017500000000440412605311413014202 00000000000000GIF89a <ÄÿÿÿÿÌÌÿ™™ÿffÿ33ÿÌÌÌÌ™™ÌffÌ33Ì™™™™ffff333333ÿÿÿ!ù, <@ÿà$Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,¶„bÉl:ŸNˆdJu@¯X§ƒÊ•0 Ù°xL.›Ïè´zÍn³ȸ\¦tÛïø¼~ÏïûÿKp)un[]ShR] b c€P VW‹‡]‰”Ÿ ¡P‚s¥¦&¢ª«¬­®¯h9„gœT“K ‡˜WP¸žK†‡ºO¼Ã•¸Ä ͰÒÓ}§×D¶ÔÜÝÞß­Ø3 ÍS"µKèó›ÍÈ ÊÍ–œš½Ðè$5ó® A@ H˜`¡Â„´j1œÈð Å‹3æI î»r Y “ð€Å‚‘èJÿ¦0€rŠJ,q½L A„–Ü1P£ÏŸ@ƒ ýö0áwHÙ`G.¤Ó§Øb¢TµªÕ†ÚÉçkаgMœ)ÂDJ#²c%ÄS˜Ù±ž¼Fa{e“1Lrê•BLÙÚ'h—l"–·,]­ š^]̸qU©œPuLjVĘ3kv£¸²çÏOÜ1¶1F›S«~ºõ Ñ«cËžÝÁk<ËØäãr¶ïßMH¹>6ðãÈ1Êrq¹ÍnÔYž{rº¥‚¹”þUoû\|Io‰=9ЉWNe¾½ûV –ŸbϰõÃkêñnR=<à‘ÏŒWu¹½—\|é©§ÿ;¸S F(¡ ¼“ ‚)¤´Â!3•ð€LëÐG‹~(t~ÑTÞ„,¶èâ‹v(„-LahcK“™dÝ/œƒ ?,ÐÀC>@ä9·y–0ÑdY—L‹wø RVZºð³“b¶e„éd"9‰…/a:0‰j6ÁO^iJIf—PBÙ&>s"v¡|öɘ(ù)h K&Gå{½Á(Æžƒ6êè…**é¤Y÷èSÍQªé¦KØfnÚõ!àu‰rj*–^ê{§¶ £ ™¶K©hàâê­}¤ªjHÆáêk{ò•+$NAký \$¿º¢ë®åDÚì´ª1Z‚ÿ´·à²â‡xÇ@ýôv(oÒỶTPʳК€ºð¦†Þ `;F±ÆfÒI]èh_b€‹"³2à>ÇÆ ´{M¯ GŒQ…rÐgo•è›pÀ¶êÅI©#Ý3êt\r¢¬Ä«Ä×°Ã@p1Ê0"޵ŸT"²ø:£³=s¨€À]t¥OŠÇlQ…|ôSíÅSOFG- G,Å2  Ó€ 6wÑ;ÐÒS@ßõKr¿eŒ,õÚl·M†Qa+}õ#%i‡]$ Þœy‰*1%ß‘ô~n'®øo9·Üs Š’ß*@v_ (uxÂx7@ù {[÷€ÿÝF0ÍÔŒ¨GDÔ®>ɇëçºR¦º«Kä¸ã˜^cä¼ch9.[Ë $á|þáßû ¾Å &SžÕÝ/t¹4qÍ™H¨?#Òeôp¥e.[œ%ÖV€/&"[Äu˜úsŠ•ï”»8#½ø'_Dóòü³ü;.¤ëq ƤëÌ%JW⎕ã 1A Ïpà—Ò‚@ÁmMá˨оèBƒt/þSÁ±hfLá£…ŽªÐ5¬Zœ )ÂÚð†8Ì¡wÈÃúð‡@ ¢‡HÄk ß…%1ÁrŠ]Et§¨Š½ì^üÃÈ6FE A1Š,8bLjªÿOÝ¡[{(WÐȸ©/‚qlŒ£LpEG| ⢠äÆ7b€\ƒ®ð®üqì¤Týˆ•D:² X㶈õGJj‘Œ¼–%79ŠÔQ <«Õ!Úó­0…‹“˜Ìä8ÉJ&KŸÌ¾ Y¿5ž©Xa¢U.DA(ä¬c–L¥* ØÊ@¾²ÄDè¶¥…Q2ã>¥q&´¤GŒùK0fc¦…ÉÈó‘žªË ÊJèg;#C2î(%lg8#$`Ÿi“Ç$8ÑùÿÓdg"[ÏúA0„N ñh Oš¸ yÄ*M‹ÔáHÚQ…Š£ -\ImjÍ}±t 3ZY€ÑŸF#SÐEp.ƒYµ4éÐ’šô£ 5*…’VCõà¢pë´*µ†Ämn(¶ÌöÏÑt¡+è$àS²¾jëê LG‹¾NÄ®]ÄkRصÈpm®`RçØj…BÆu @k(`'KÙ3$¤#ƒ ":ŒG‚ÂRA¨ŠF2ÌF¾i³™å¬¬jWÁêÕ:lÞNð?— À³(AF:w)±ö·€¼,’»×B#á, þç9€s-L ëväuáÿ¹(RÞñ×_^¸àuERÇÕÌ*Sёٔ‡‚ép%Öeïm­ ¼è.·ÓÉê ¦W41‘«si~‹Ë´óÚ0s.Ý}\ØÙ”0x¸åd†³ÒMñ¥6L+è·ZjŸñ Z¢\éÒ— %F}å D1ÇáÃfºÞ4ÏÅÎÃzÞ[ÓuæÇÄô!î¦láËøÒR–IlAÆrŒŽí‡d¶´Ogñ\²\žìap€XÄX^‰uÊ1¼ ƒQ¢¿ñ œœ&„q¸l¦l XЂc|œùÂ$s.‰ü ¯¤+Édf²W–h0’ñŃt®Òœtœfó0ˈÆAmñàDó@B†Hlo†ŒMh˜ÎÊxK[.ç{̵{ó=¼A{? Äæ©íèVÇ Âœh´«qPáäŒð;iBb‘ÍÀLMÔ²Çò5^ )l4»Z³N¶zG¢9e÷À›ü]Û•m`Xs!ÅÔÎA,£«igû¸Ä;’¬¿Mîr›ûÜèN·º×Ín"„;yaws-2.0.2/test/t2/www/hello.txt0000664000175000017500000000001612605311413013406 00000000000000Hello, World! yaws-2.0.2/test/t2/www/test_upload_ssl.yaws0000664000175000017500000000320612605311413015657 00000000000000 %% inspired from upload.yaws, slightly simplified. -record(state, {acc, last }). out(A) -> %% make sure it is post method 'POST' = yaws_api:http_request_method(yaws_api:arg_req(A)), case get_props(A) of {error, Reason} -> {ehtml, "error"}; {get_more, Cont, NewState} = GetMore -> GetMore; {ok, AllParts} -> {ehtml, "ok"} end. get_state(A) -> case A#arg.state of undefined -> #state{acc = [], last = false}; State0 -> State0 end. get_props(A) -> Parse = yaws_api:parse_multipart_post(A), State = get_state(A), case Parse of {cont, Cont, Res} -> case add_file_chunk(A, Res, State) of {done, Result} -> error_logger:info_msg("Ok, got: ~p", [Result]), {ok, Result}; {cont, NewState} -> {get_more, Cont, NewState} end; {result, Res} -> case add_file_chunk(A, Res, State#state{last = true}) of {done, Result} -> {ok, Result}; {cont, _} -> {error, ooops} end; {error, Reason} = Error -> io:format("Error : ~p", [Reason]), Error end. add_file_chunk(A, [H | Tail], #state{acc = Acc0} = State0) -> Acc1 = [H | Acc0], State1 = State0#state{acc = Acc1}, add_file_chunk(A, Tail, State1); add_file_chunk(A, [], #state{last = false} = State) -> {cont, State}; add_file_chunk(A, [], #state{last = true, acc = RAcc} = State) -> Data = lists:reverse(RAcc), {done, Data}. yaws-2.0.2/test/t2/www/exhtml.yaws0000664000175000017500000000014012605311413013746 00000000000000 out(_Arg) -> Struct = {p, [{id, <<"foo">>}], <<"bar">>}, {exhtml, Struct}. yaws-2.0.2/test/t2/www/index.html0000664000175000017500000000002612605311413013540 00000000000000

Hello World!

yaws-2.0.2/test/t2/shapertest.erl0000664000175000017500000000150112605311413013604 00000000000000-module(shapertest). -behaviour(yaws_shaper). -export([ check/1, update/3 ]). -include("yaws.hrl"). -include("yaws_api.hrl"). -define(SHAPER_DB, shaper_db). check(Ip) -> try_create(), case ets:lookup(?SHAPER_DB, Ip) of [{Ip, NbHit}] when NbHit > 2 -> {deny, 503, "Request quota exceeded"}; _ -> allow end. update(Ip, Hits, _Bytes) -> try_create(), case ets:member(?SHAPER_DB, Ip) of true -> ets:update_counter(?SHAPER_DB, Ip, Hits); false -> ets:insert(?SHAPER_DB, {Ip, Hits}) end. try_create() -> case ets:info(?SHAPER_DB) of undefined -> ets:new(?SHAPER_DB, [set, public, named_table, {heir, whereis(yaws_server), []}]); _ -> ok end. yaws-2.0.2/test/t2/throwtest.erl0000664000175000017500000000011612605311413013466 00000000000000-module(throwtest). -export([out/1]). out(_Arg) -> throw({status, 200}). yaws-2.0.2/test/t2/rewritetest.erl0000664000175000017500000000145312605311413014011 00000000000000-module(rewritetest). -export([arg_rewrite/1]). -include("yaws.hrl"). -include("yaws_api.hrl"). arg_rewrite(Arg) -> Url = yaws_api:request_url(Arg), case Url#url.path of "/rewrite" -> Req0 = Arg#arg.req, Req1 = Req0#http_request{path={abs_path,"/hello.txt"}}, Arg#arg{req=Req1}; "/redirect" -> L = "http://www.yakaz.com", H = [{header, {location, L}}], RwResp = #rewrite_response{status=301, headers=H}, Arg#arg{state=RwResp}; "/response" -> H = [{header, {content_type, "text/plain"}}], C = <<"Goodbye, Cruel World!">>, RwResp = #rewrite_response{status=200, headers=H, content=C}, Arg#arg{state=RwResp}; _ -> Arg end. yaws-2.0.2/test/t2/reentranttest.erl0000664000175000017500000000116412605311413014331 00000000000000-module(reentranttest). -export([out/1]). -include("yaws.hrl"). -include("yaws_api.hrl"). out(Arg) -> Url = yaws_api:request_url(Arg), case Url#url.path of "/reentranttest/status" -> {page, {[{status, 201}], "/hello.txt"}}; "/reentranttest/delayed_headers" -> Hdrs = [{header, {cache_control, "no-cache"}}, {header, "Etag: static-tag"}, {header, "X-Delayed-Header: true"}], {page, {Hdrs, "/hello.txt"}}; _ -> Reason = "unknown path: " ++ Url#url.path, [{status, 500}, {html, Reason}] end. yaws-2.0.2/test/t2/wrap_log.erl0000664000175000017500000000013712605311413013240 00000000000000-module(wrap_log). -export([out/1]). out(_Arg) -> yaws_log ! minute10, {status, 200}. yaws-2.0.2/test/t2/yaws.conf.in0000664000175000017500000000600112605311413013155 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 port = 8000 listen = 0.0.0.0 deflate = true docroot = @abs_srcdir@/www @abs_builddir@/docroot-test appmods = streamtest wrap_log port = 8002 listen = 0.0.0.0 appmods = port = 8003 listen = 0.0.0.0 docroot = @abs_top_srcdir@/www appmods = port = 8004 listen = 0.0.0.0 docroot = @abs_builddir@/docroot-test appmods = port = 8005 listen = 0.0.0.0 appmods = port = 8006 listen = 0.0.0.0 docroot = @abs_srcdir@/www auth_log = true partial_post_size = 2048000 php_handler = arg_rewrite_mod = rewritetest expires = expires = expires = <*/*, always> appmods = posttest reentranttest flushtest port = 8007 listen = 0.0.0.0 docroot = @abs_srcdir@/www shaper = shapertest port = 8008 listen = 0.0.0.0 docroot = @abs_srcdir@/www appmods = port = 8009 listen = 0.0.0.0 appmods = port = 8010 listen = 0.0.0.0 docroot = @abs_top_srcdir@/www index_files = index.html /testdir port = 8011 listen = 0.0.0.0 docroot = @abs_top_srcdir@/www dispatchmod = dispatchmod_tester port = 8012 listen = 0.0.0.0 docroot = @abs_builddir@/docroot-test appmods = appmod1 port = 8013 listen = 0.0.0.0 docroot = @abs_top_srcdir@/www appmods = port = 8014 listen = 0.0.0.0 appmods = port = 8443 listen = 0.0.0.0 docroot = @abs_srcdir@/www keyfile = @abs_top_srcdir@/ssl/yaws-key.pem certfile = @abs_top_srcdir@/ssl/yaws-cert.pem depth = 0 yaws-2.0.2/test/t2/appmod2.erl0000664000175000017500000000031212605311413012763 00000000000000-module(appmod2). -export([out/1]). out(Arg) -> Path = yaws_api:arg_server_path(Arg), Stack = get(appmod_stack), put(appmod_stack, Stack++", appmod2["++Path++"]"), {page, "/appmod1"}. yaws-2.0.2/test/t2/dispatchmod_tester.erl0000664000175000017500000000101712605311413015311 00000000000000-module(dispatchmod_tester). -export([dispatch/1]). -include("yaws_api.hrl"). dispatch(#arg{clisock=Sock}=A) -> {abs_path, Path} = (A#arg.req)#http_request.path, case Path of "/done" -> ok = gen_tcp:send(Sock, <<"HTTP/1.1 204 No Content\r\nX-DispatchMod: true\r\n\r\n">>), done; "/closed" -> ok = gen_tcp:send(Sock, <<"HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n">>), gen_tcp:close(Sock), closed; _ -> continue end. yaws-2.0.2/test/t2/Makefile.am0000664000175000017500000000234512605311413012761 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl \ appmod1.erl \ appmod2.erl \ appmod3.erl \ cache_appmod_test.erl \ dispatchmod_tester.erl \ flushtest.erl \ forwarded_for_test.erl \ jsontest.erl \ phptest.erl \ posttest.erl \ reentranttest.erl \ rewritetest.erl \ shapertest.erl \ streamtest.erl \ throwtest.erl \ wrap_log.erl EXTRA_DIST = $(MODULES) www EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test prepare-test:: $(AM_V_at)dd if=/dev/zero of=./docroot-test/1000.txt bs=1024 count=1000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/2000.txt bs=1024 count=2000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/3000.txt bs=1024 count=3000 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/10000.txt bs=1024 count=10000 >/dev/null 2>&1 distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/src/0000775000175000017500000000000012605312014011241 500000000000000yaws-2.0.2/test/src/Makefile.in0000664000175000017500000003560412605311446013246 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = test.erl tftest.erl EXTRA_DIST = $(MODULES) EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) clean-local: $(AM_V_at)rm -f $(EBIN_FILES) %.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o . $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/src/test.erl0000664000175000017500000000036112605311413012646 00000000000000-module(test). -compile(export_all). run([]) -> erlang:halt(0); run([E|Eunits]) -> try io:format("Running ~p~n", [E]), ok = E:test(), run(Eunits) catch _:_ -> erlang:halt(1) end. yaws-2.0.2/test/src/tftest.erl0000664000175000017500000000757312605311413013214 00000000000000-module(tftest). %%% external exports -export([start/0, start/1]). %% Use these functions if you want to start/stop coverage yourself -export([cover_start/1, cover_stop/1]). -export([get_headers/1]). -include("../include/tftest.hrl"). start() -> start(true). start([_]) -> start(false); start(DoHalt) -> spawn(fun() -> start1(DoHalt) end). start1(DoHalt) -> process_flag(trap_exit, true), Pid = spawn_link(fun() -> start2() end), receive {'EXIT', Pid, tests_ok} -> {ok, Wd} = file:get_cwd(), io:format("\n** All ~s tests completed successfully.\n", [Wd]), dohalt(DoHalt, 0); {'EXIT', Pid, {tests_failed, M, Line, Error}} -> {ok, Wd} = file:get_cwd(), io:format("**************\n" "** test failed at ~p.erl:~p\n" " in ~p\n" "** reason: \n" " ~p\n" "**************\n", [M, Line, Wd, Error]), %% allow time to flush output timer:sleep(1000), dohalt(DoHalt, 1); {'EXIT', Pid, R} -> io:format("**************\n" "** test failed ~p\n", [R]), %% allow time to flush output timer:sleep(1000), dohalt(DoHalt, 1) end. start2() -> CM = case catch app_test:cover_modules() of {'EXIT', _} -> []; Mods -> cover_start(Mods) end, application:load(sasl), application:set_env(sasl, errlog_type, error), application:start(sasl), TEST = os:getenv("TEST"), case catch app_test_start(TEST) of ok -> cover_stop(CM), exit(tests_ok); Error -> {M,Line} = case get('$line') of undefined -> {undefined, undefined}; ML -> ML end, exit({tests_failed, M, Line, Error}) end. app_test_start(false) -> app_test:start(); app_test_start(Mod) -> app_test:start([list_to_atom(Mod)]). %% @spec (Mods::[atom()]) -> CoveredModules::[atom()] cover_start(Mods) -> cover:start(), %% First cover-compile listed modules CM = lists:foldl( fun (M, Ms) -> case module_source_or_beam(M) of {source, File} -> {ok, _} = cover:compile(File), [M|Ms]; {beam, File} -> {ok, _} = cover:compile_beam(File), [M|Ms]; _ -> Ms end end, [], Mods), %% Now merge any previous state case file:open(cover_state_file(), [read]) of {ok, F} -> file:close(F), cover:import(cover_state_file()); _ -> ok end, CM. module_source_or_beam(M) -> CInfo = M:module_info(compile), {value, {options, COptions}} = lists:keysearch(options, 1, CInfo), Source = case lists:keysearch(source, 1, CInfo) of {value, {source, SFile}} -> case file:open(SFile, [read]) of {ok, SFd} -> file:close(SFd), SFile; _ -> unknown end; _ -> unknown end, Beam = case lists:keysearch(outdir, 1, COptions) of {value, {outdir, Dir = "/" ++ _}} -> BFile = filename:join(Dir, atom_to_list(M) ++ ".beam"), case file:open(BFile, [read]) of {ok, BFd} -> file:close(BFd), BFile; _ -> unknown end; _ -> unknown end, case lists:member(debug_info, COptions) of true when Beam =/= unknown -> {beam, Beam}; _ when Source =/= unknown -> {source, Source}; _ -> false end. cover_state_file() -> "/tmp/COVER.coverdata". %% @spec (CoveredModules::[atom()]) -> void() cover_stop([]) -> ok; cover_stop(Mods) -> lists:foreach(fun (M) -> cover:analyse_to_file(M) end, Mods), cover:export(cover_state_file()), % Keep state cover:stop(), ok. dohalt(true, Int) -> erlang:halt(Int); dohalt(false, _) -> ok. %% read out the http headers from a socket get_headers(C) -> get_headers(C, gen_tcp:recv(C, 0), []). get_headers(_C, {ok, http_eoh}, Ack) -> Ack; get_headers(_C, {error, R}, _) -> {error, R}; get_headers(C, {ok, H}, Ack) -> get_headers(C, gen_tcp:recv(C, 0), [H|Ack]). yaws-2.0.2/test/src/Makefile.am0000664000175000017500000000076212605311413013224 00000000000000include @top_srcdir@/include.mk MODULES = test.erl tftest.erl EXTRA_DIST = $(MODULES) EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) clean-local: $(AM_V_at)rm -f $(EBIN_FILES) %.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o . $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/t1/0000775000175000017500000000000012605312015010777 500000000000000yaws-2.0.2/test/t1/Makefile.in0000664000175000017500000004423212605311446013000 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t1 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ EXTRA_DIST = wgettest runtest ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf DATAFILE_BASE = small_datafile.dat DATAFILE = ./docroot-test/$(DATAFILE_BASE) TMP_DATAFILE = ./docroot-test/tmpdatafile CHECK_WITH_CURL = \ set -e; \ rm -f $(TMP_DATAFILE); \ curl -s -m 5 -o $(TMP_DATAFILE) http://localhost:8002/$(DATAFILE_BASE); \ cmp -s $(DATAFILE) $(TMP_DATAFILE) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t1/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t1/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test check-local: log start wait-started t1 t2 t3 t4 t5 t6 t7 stop json log: @echo @echo " ==== TESTS ==== " @echo prepare-test:: $(AM_V_at)cp $(YAWS_CONF) $(YAWS_CONF).orig $(AM_V_at)dd if=/dev/zero of=$(DATAFILE) bs=10 count=1 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/131072.dat bs=1024 count=128 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/1048576.dat bs=1024 count=1024 >/dev/null 2>&1 # $(AM_V_at)dd if=/dev/zero of=./docroot-test/8388608.dat bs=1024 count=8192 >/dev/null 2>&1 clean-test:: $(AM_V_at)[ ! -f $(YAWS_CONF).orig ] || mv $(YAWS_CONF).orig $(YAWS_CONF) $(AM_V_at)rm -fr "./localhost:8001" newconf: $(AM_V_at)cp $(YAWS_CONF).orig $(YAWS_CONF) t1: @echo "wget test" $(AM_V_at)rm -fr "./localhost:8001" $(AM_V_at)$(SHELL) @srcdir@/wgettest $(AM_V_at)rm -fr "./localhost:8001" t2: @echo "sendfile test" $(AM_V_at)$(SHELL) @srcdir@/runtest 131072 1048576 #8388608 t3: $(AM_V_at)if [ -z $(CURL) ]; then \ echo "SKIPPED - curl is required to run these tests"; \ else \ echo "check-with-curl (max_num_cached_files = 0)"; \ cp $(YAWS_CONF).orig $(YAWS_CONF); \ echo 'max_num_cached_files = 0' >> $(YAWS_CONF); \ $(top_builddir)/test/bin/yaws --id testid --hup >/dev/null; \ $(CHECK_WITH_CURL); \ fi t4: $(AM_V_at)if [ -z $(CURL) ]; then \ echo "SKIPPED - curl is required to run these tests"; \ else \ echo "check-with-curl (max_num_cached_bytes = 0)"; \ cp $(YAWS_CONF).orig $(YAWS_CONF); \ echo 'max_num_cached_bytes = 0' >> $(YAWS_CONF); \ $(top_builddir)/test/bin/yaws --id testid --hup >/dev/null; \ $(CHECK_WITH_CURL); \ fi t5: $(AM_V_at)if [ -z $(CURL) ]; then \ echo "SKIPPED - curl is required to run these tests"; \ else \ echo "check-with-curl (max_size_cached_file = 0)"; \ cp $(YAWS_CONF).orig $(YAWS_CONF); \ echo 'max_size_cached_file = 0' >> $(YAWS_CONF); \ $(top_builddir)/test/bin/yaws --id testid --hup >/dev/null; \ $(CHECK_WITH_CURL); \ fi t6: $(AM_V_at)if [ -z $(CURL) ]; then \ echo "SKIPPED - curl is required to run these tests"; \ else \ echo "check-with-curl (max_num_cached_bytes = 5 / max_size_cached_file = 50)";\ cp $(YAWS_CONF).orig $(YAWS_CONF); \ echo 'max_num_cached_bytes = 5' >> $(YAWS_CONF); \ echo 'max_size_cached_file = 50' >> $(YAWS_CONF); \ $(top_builddir)/test/bin/yaws --id testid --hup >/dev/null; \ $(CHECK_WITH_CURL); \ fi # Verify redirection does not create URIs with multiple adjacent slashes Test # submitted by James Lee t7: newconf hup $(AM_V_at)if [ -z $(CURL) ]; then \ echo "SKIPPED - curl is required to run these tests"; \ else \ echo "redirect test"; \ loc=`curl -s -m 5 -i http://localhost:8003/foo | \ perl -ne 'print "$$1\n" if (m#Location:\s+http://(.+)#)' | \ grep //`; \ [ "${loc}" = "" ] && exit 0 || exit 1; \ fi json: @echo "json test" $(AM_V_at)$(ERL) -noinput $(ERL_FLAGS) -eval \ 'case json2:test() of ok -> halt(0); _ -> halt(1) end' # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t1/wgettest0000775000175000017500000000066412605311413012522 00000000000000#!/bin/sh wget -q -r http://localhost:8001 # Give yaws some time to write out its report.log file count=10 while [ $count -gt 0 ]; do # check it report.log # count lines to work around grep exit status portability issues total=`cat logs/report.log | grep -v www/arg.yaws | \ grep -v www/arg2.yaws | grep -v ^=ERROR | grep ERROR 2>&1 | wc -l` [ "$total" -eq 0 ] || exit 1 count=`expr $count - 1` done exit 0 yaws-2.0.2/test/t1/yaws.conf.in0000664000175000017500000000154212605311413013161 00000000000000logdir = @abs_builddir@/logs trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 port = 8001 listen = 0.0.0.0 deflate = true docroot = @abs_top_srcdir@/www port = 8002 listen = 0.0.0.0 listen_backlog = 512 deflate = true docroot = @abs_builddir@/docroot-test port = 8003 listen = 0.0.0.0 deflate = true docroot = @abs_builddir@/docroot-test / = localhost yaws-2.0.2/test/t1/runtest0000775000175000017500000000550512605311413012357 00000000000000#!/bin/sh # # Load Yaws with a number of concurrent curl requests for files of varying # size up to the fd limit to make sure the sendfile driver is not serializing # requests and creating a request queue so long that it eats up all the available # fds. The file sizes are passed into this script as command-line arguments. # sizes="$@" if [ -n "$RUNTEST_CURLS" ]; then fdlimit=`expr $RUNTEST_CURLS / $#` else fdlimit=`ulimit -n` fdlimit=`expr $fdlimit / 8` [ $fdlimit -gt 1024 ] && fdlimit=1024 if [ `uname -s` = Darwin ]; then proclimit=`ulimit -u` if [ $proclimit -lt $fdlimit ]; then newproclimit=`expr $fdlimit \* $#` ulimit -u $newproclimit if [ $? -ne 0 ]; then echo unable to run enough processes for this test, skipping echo please raise your max process limit via '"'sysctl -w kern.maxprocperuid=$newproclimit'"' exit 0 fi fi fi fi rm -f erl_crash.dump outdir=./runtest_out$$ trap "rm -rf $outdir" HUP INT EXIT mkdir -p $outdir i=0 numcurls=`expr $fdlimit '*' $#` echo " starting $numcurls background curl tasks" while [ $i -lt $fdlimit ]; do for j in $sizes; do curlhdrs=curl-${j}-${i}.txt curl -D $outdir/$curlhdrs --connect-timeout 60 -s \ -o $outdir/${j}-${i}.dat http://localhost:8002/$j.dat >/dev/null 2>&1 & p=$! ( cd $outdir ; rm -f ${p}.txt ; ln -s $curlhdrs ${p}.txt ) curls="$curls $p" done i=`expr $i + 1` done echo " waiting for curl tasks to complete" for job in $curls; do kill -0 $job 2>/dev/null if [ $? -eq 0 ]; then wait $job result=$? if [ $result -ne 0 ]; then echo failure in background curl job $job, exit status $result cat $outdir/${job}.txt sleep 5 [ -f erl_crash.dump ] && echo 'Yaws crashed! See logs/report.log and erl_crash.dump for details' exit 1 else ( cd $outdir ; rm -f `readlink ${job}.txt` ${job}.txt ) fi fi done echo " verifying all retrieved files" # On some systems (e.g. MacBook Pro) it seems to take a bit for the # file writes to actually appear. The sleep and ls below help the loop # avoid failing due to files that just haven't appeared yet. sleep 5 ls $outdir >/dev/null 2>&1 for j in $sizes; do count=`ls -1 $outdir/${j}*.dat | wc -l` if [ $count -ne $fdlimit ]; then echo not all $j byte data files retrieved: expected $fdlimit, got $count exit 1 fi none=`ls -l $outdir/${j}*.dat | awk '{print $5}' | grep -v $j` if [ -n "$none" ]; then echo not all $j byte data files have the right size exit 1 fi done if [ -f erl_crash.dump ]; then echo yaws crashed, see logs/report.log and erl_crash.dump for details exit 1 fi exit 0 yaws-2.0.2/test/t1/Makefile.am0000664000175000017500000000713412605311413012761 00000000000000include @top_srcdir@/test/support/include.mk EXTRA_DIST = wgettest runtest ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF=yaws.conf DATAFILE_BASE = small_datafile.dat DATAFILE = ./docroot-test/$(DATAFILE_BASE) TMP_DATAFILE = ./docroot-test/tmpdatafile CHECK_WITH_CURL = \ set -e; \ rm -f $(TMP_DATAFILE); \ curl -s -m 5 -o $(TMP_DATAFILE) http://localhost:8002/$(DATAFILE_BASE); \ cmp -s $(DATAFILE) $(TMP_DATAFILE) all-local: clean-local: clean-test check-local: log start wait-started t1 t2 t3 t4 t5 t6 t7 stop json log: @echo @echo " ==== TESTS ==== " @echo prepare-test:: $(AM_V_at)cp $(YAWS_CONF) $(YAWS_CONF).orig $(AM_V_at)dd if=/dev/zero of=$(DATAFILE) bs=10 count=1 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/131072.dat bs=1024 count=128 >/dev/null 2>&1 $(AM_V_at)dd if=/dev/zero of=./docroot-test/1048576.dat bs=1024 count=1024 >/dev/null 2>&1 # $(AM_V_at)dd if=/dev/zero of=./docroot-test/8388608.dat bs=1024 count=8192 >/dev/null 2>&1 clean-test:: $(AM_V_at)[ ! -f $(YAWS_CONF).orig ] || mv $(YAWS_CONF).orig $(YAWS_CONF) $(AM_V_at)rm -fr "./localhost:8001" newconf: $(AM_V_at)cp $(YAWS_CONF).orig $(YAWS_CONF) t1: @echo "wget test" $(AM_V_at)rm -fr "./localhost:8001" $(AM_V_at)$(SHELL) @srcdir@/wgettest $(AM_V_at)rm -fr "./localhost:8001" t2: @echo "sendfile test" $(AM_V_at)$(SHELL) @srcdir@/runtest 131072 1048576 #8388608 t3: $(AM_V_at)if [ -z $(CURL) ]; then \ echo "SKIPPED - curl is required to run these tests"; \ else \ echo "check-with-curl (max_num_cached_files = 0)"; \ cp $(YAWS_CONF).orig $(YAWS_CONF); \ echo 'max_num_cached_files = 0' >> $(YAWS_CONF); \ $(top_builddir)/test/bin/yaws --id testid --hup >/dev/null; \ $(CHECK_WITH_CURL); \ fi t4: $(AM_V_at)if [ -z $(CURL) ]; then \ echo "SKIPPED - curl is required to run these tests"; \ else \ echo "check-with-curl (max_num_cached_bytes = 0)"; \ cp $(YAWS_CONF).orig $(YAWS_CONF); \ echo 'max_num_cached_bytes = 0' >> $(YAWS_CONF); \ $(top_builddir)/test/bin/yaws --id testid --hup >/dev/null; \ $(CHECK_WITH_CURL); \ fi t5: $(AM_V_at)if [ -z $(CURL) ]; then \ echo "SKIPPED - curl is required to run these tests"; \ else \ echo "check-with-curl (max_size_cached_file = 0)"; \ cp $(YAWS_CONF).orig $(YAWS_CONF); \ echo 'max_size_cached_file = 0' >> $(YAWS_CONF); \ $(top_builddir)/test/bin/yaws --id testid --hup >/dev/null; \ $(CHECK_WITH_CURL); \ fi t6: $(AM_V_at)if [ -z $(CURL) ]; then \ echo "SKIPPED - curl is required to run these tests"; \ else \ echo "check-with-curl (max_num_cached_bytes = 5 / max_size_cached_file = 50)";\ cp $(YAWS_CONF).orig $(YAWS_CONF); \ echo 'max_num_cached_bytes = 5' >> $(YAWS_CONF); \ echo 'max_size_cached_file = 50' >> $(YAWS_CONF); \ $(top_builddir)/test/bin/yaws --id testid --hup >/dev/null; \ $(CHECK_WITH_CURL); \ fi # Verify redirection does not create URIs with multiple adjacent slashes Test # submitted by James Lee t7: newconf hup $(AM_V_at)if [ -z $(CURL) ]; then \ echo "SKIPPED - curl is required to run these tests"; \ else \ echo "redirect test"; \ loc=`curl -s -m 5 -i http://localhost:8003/foo | \ perl -ne 'print "$$1\n" if (m#Location:\s+http://(.+)#)' | \ grep //`; \ [ "${loc}" = "" ] && exit 0 || exit 1; \ fi json: @echo "json test" $(AM_V_at)$(ERL) -noinput $(ERL_FLAGS) -eval \ 'case json2:test() of ok -> halt(0); _ -> halt(1) end' # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/support/0000775000175000017500000000000012605312014012166 500000000000000yaws-2.0.2/test/support/include.mk0000664000175000017500000001143112605311413014064 00000000000000WAIT_TIME=10 ERL_GENERIC_FLAGS = -pa $(top_srcdir) -pa $(top_builddir) \ -pa $(top_builddir)/ebin -pa $(top_builddir)/test \ -pa $(top_builddir)/test/src -pa $(top_builddir)/test/ibrowse/ebin \ -pa $(top_builddir)/c_src/.libs # Override this variable if you want to change the yaws's configuration YAWS_CONF ?= $(top_builddir)/test/support/yaws.conf DEPS = $(top_builddir)/test/src/tftest.beam \ $(top_builddir)/test/src/test.beam \ $(top_builddir)/priv/epam \ $(top_builddir)/priv/lib/setuid_drv.so \ $(abs_top_builddir)/priv/mime.types \ $(top_builddir)/ebin/yaws.beam ifeq ($(HAVE_ERLANG_SENDFILE),true) DEPS += $(top_builddir)/priv/lib/yaws_sendfile_drv.so endif start: $(top_builddir)/test/bin/yaws quiet-stop prepare-test $(AM_V_at)$(top_builddir)/test/bin/yaws --sname test --daemon --id testid --conf $(YAWS_CONF) wait-started: $(top_builddir)/test/bin/yaws $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --wait-started=$(WAIT_TIME);\ err=$$?; \ if test $$err -ne 0; then \ cat logs/report.log; \ fi; \ exit $$err wait-stopped: $(top_builddir)/test/bin/yaws $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --wait-stopped=$(WAIT_TIME) stop: $(top_builddir)/test/bin/yaws $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --stop >/dev/null quiet-stop: $(top_builddir)/test/bin/yaws $(AM_V_at)($(top_builddir)/test/bin/yaws --id testid --stop >/dev/null || true) $(AM_V_at)($(top_builddir)/test/bin/yaws --id testid --wait-stopped=$(WAIT_TIME) >/dev/null || true) hup: $(top_builddir)/test/bin/yaws $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --hup >/dev/null status: $(top_builddir)/test/bin/yaws $(AM_V_at)$(top_builddir)/test/bin/yaws --id testid --status >/dev/null i: $(top_builddir)/test/bin/yaws $(AM_V_at)$(top_builddir)/test/bin/yaws --sname test -i --id testid --conf $(YAWS_CONF) connect: $(top_builddir)/test/bin/yaws $(AM_V_at)$(ERL) -sname client -remsh test@`hostname` test: check app-test: $(DEPS) all start wait-started do-test stop wait-stopped do-test: $(AM_V_at)$(ERL) -sname tftest -noinput $(ERL_FLAGS) -s tftest; \ err=$$?; \ if test $$err -ne 0; then \ $(MAKE) quiet-stop; \ cat logs/report.log; \ fi; \ exit $$err app_test.beam: $(top_builddir)/test/ibrowse/include/ibrowse.hrl $(top_builddir)/test/ibrowse/ebin/ibrowse.beam %.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o . $< $(top_builddir)/test/bin/yaws: $(AM_V_at)$(INSTALL) -d $(top_builddir)/test/bin $(AM_V_GEN)(cd $(top_srcdir)/scripts && \ YAWSDIR='$(abs_top_builddir)' \ VARDIR='$(abs_top_builddir)' \ ERLBINDIR='$(ERLANG_ERTS_DIR)/bin' \ ERL='$(ERL)' WERL='$(WERL)' \ ./gen-yaws > $(abs_top_builddir)/test/bin/yaws) $(AM_V_at)chmod +x $(top_builddir)/test/bin/yaws $(top_builddir)/test/ibrowse/ebin/ibrowse.beam \ $(top_builddir)/test/ibrowse/include/ibrowse.hrl: $(AM_V_at)$(MAKE) ibrowse $(DEPS): @echo $@ $(AM_V_at)(cd $(top_builddir) && $(MAKE)); ibrowse: fetch-ibrowse $(AM_V_at)(cd $(top_builddir)/test/ibrowse && $(ESCRIPT) ./rebar compile) IBROWSE_URI = https://github.com/cmullaparthi/ibrowse.git IBROWSE_DOWNLOAD_URI = https://github.com/cmullaparthi/ibrowse/tarball/v3.0.4 IBROWSE_TGZ = $(top_builddir)/test/ibrowseibrowse.tar.gz IBROWSE_VSN = $(top_builddir)/test/ibrowse/.version fetch-ibrowse: $(AM_V_at)nvsn=`git ls-remote -h $(IBROWSE_URI) master 2>/dev/null` ; \ git_ok=$$? ; \ set -e ; \ if [ -f $(IBROWSE_VSN) -a $$git_ok -eq 0 ] ; then \ nvsn=`echo $$nvsn | awk '{print $$1}'` ; \ vsn=`cat $(IBROWSE_VSN)` ; \ [ "$$nvsn" = "$$vsn" ] || fetch=yes ; \ else \ if [ ! -f $(IBROWSE_VSN) -a $$git_ok -ne 0 ] ; then \ echo "error: ibrowse repository $(IBROWSE_URI) unreachable" ; \ exit 1 ; \ fi ; \ [ $$git_ok -eq 0 ] && fetch=yes ; \ fi ; \ if [ -n "$$fetch" ] ; then \ rm -rf ibrowse ; \ echo " FETCH ibrowse" ; \ curl -s -L -o $(IBROWSE_TGZ) $(IBROWSE_DOWNLOAD_URI) ; \ dir=`tar ztf $(IBROWSE_TGZ) | head -1 | sed -e 's/\/$$//'` ; \ tar zxf $(IBROWSE_TGZ) ; \ mv $$dir $(top_builddir)/test/ibrowse ; \ rm -f $(IBROWSE_TGZ) ; \ echo $$nvsn > $(IBROWSE_VSN) ; \ fi ##### # Overridable targets (to override a target, use '::' separator) # Note: using '::', all targets with the same name will be executed #### prepare-test:: clean-test $(AM_V_at)$(INSTALL) -d docroot-test $(AM_V_at)$(INSTALL) -d logs clean-test:: $(AM_V_at)rm -fr logs docroot-test erl_crash.dump report.log *.access *.auth .PHONY: ibrowse .NOTPARALLEL: # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/support/yaws.conf.in0000664000175000017500000000072212605311413014350 00000000000000logdir = +@abs_top_builddir@/test/logs trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 port = 8000 listen = 0.0.0.0 docroot = @abs_top_srcdir@/www yaws-2.0.2/test/t13/0000775000175000017500000000000012605312015011062 500000000000000yaws-2.0.2/test/t13/Makefile.in0000664000175000017500000003622112605311446013062 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t13 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl \ max_connections.erl EXTRA_DIST = $(MODULES) EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t13/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t13/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t13/max_connections.erl0000664000175000017500000000014612605311413014677 00000000000000-module(max_connections). -export([out/1]). out(_Arg) -> timer:sleep(3000), [{status, 204}]. yaws-2.0.2/test/t13/app_test.erl0000664000175000017500000000141612605311413013330 00000000000000-module(app_test). -compile(export_all). -include_lib("ibrowse/include/ibrowse.hrl"). -include("tftest.hrl"). %% Way to invoke just one test start([F]) -> ?line {ok, _} = ibrowse:start_link(), apply(app_test, F, []), ibrowse:stop(). start() -> io:format("\n ==== MAIN TESTS ==== \n\n", []), ?line {ok, _} = ibrowse:start_link(), test_max_connections(), ibrowse:stop(). test_max_connections() -> io:format("max connections\n",[]), spawn(fun() -> {ok,"204",_,_} = ibrowse:send_req("http://localhost:8000", [], get), exit(normal) end), timer:sleep(1000), {error, retry_later} = ibrowse:send_req("http://localhost:8000", [], get), ok. yaws-2.0.2/test/t13/yaws.conf.in0000664000175000017500000000101512605311413013237 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 max_connections = 1 port = 8000 listen = 0.0.0.0 appmods = yaws-2.0.2/test/t13/Makefile.am0000664000175000017500000000104212605311413013034 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl \ max_connections.erl EXTRA_DIST = $(MODULES) EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/t9/0000775000175000017500000000000012605312015011007 500000000000000yaws-2.0.2/test/t9/bad_redirect4.conf0000664000175000017500000000014212605311413014267 00000000000000 /bad_redirect = 601 yaws-2.0.2/test/t9/Makefile.in0000664000175000017500000003630212605311446013007 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t9 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl EXTRA_DIST = $(MODULES) bad_redirect1.conf bad_redirect2.conf bad_redirect3.conf bad_redirect4.conf www EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t9/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t9/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t9/bad_redirect2.conf0000664000175000017500000000014212605311413014265 00000000000000 /bad_redirect = 301 yaws-2.0.2/test/t9/bad_redirect3.conf0000664000175000017500000000017012605311413014267 00000000000000 /bad_redirect = 404 http://yaws.hyber.org yaws-2.0.2/test/t9/app_test.erl0000664000175000017500000002131312605311413013253 00000000000000-module(app_test). -compile(export_all). -include("yaws.hrl"). -include_lib("ibrowse/include/ibrowse.hrl"). -include("tftest.hrl"). %% Way to invoke just one test start([F]) -> ?line {ok, _} = ibrowse:start_link(), apply(app_test, F, []), ibrowse:stop(). start() -> io:format("\n ==== REDIRECT TESTS ==== \n\n", []), ?line {ok, _} = ibrowse:start_link(), test_default_redirect(), test_301_redirect(), test_404_redirect(), test_bad_redirect(), test_redirect_url_encode(), test_redirect_querystring(), test_redirect_post(), ibrowse:stop(). test_default_redirect() -> io:format("default_redirect (302)\n", []), %% /default_redirect1 -> /redir (relative-url + append) Uri1 = "http://localhost:8000/default_redirect1/index.html", ?line {ok, "302", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), ?line "http://localhost:8000/redir/default_redirect1/index.html" = proplists:get_value("Location", Hdrs1), %% /default_redirect2 -> /redir (relative-url + noappend) Uri2 = "http://localhost:8000/default_redirect2/index.html", ?line {ok, "302", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line "http://localhost:8000/redir" = proplists:get_value("Location", Hdrs2), %% /default_redirect3 -> /redir (absolute-url + append) Uri3 = "http://localhost:8000/default_redirect3/index.html", ?line {ok, "302", Hdrs3, _} = ibrowse:send_req(Uri3, [], get), ?line "http://yaws.hyber.org/default_redirect3/index.html" = proplists:get_value("Location", Hdrs3), %% /default_redirect4 -> /redir (absolute-url + noappend) Uri4 = "http://localhost:8000/default_redirect4/index.html", ?line {ok, "302", Hdrs4, _} = ibrowse:send_req(Uri4, [], get), ?line "http://yaws.hyber.org/" = proplists:get_value("Location", Hdrs4), ok. test_301_redirect() -> io:format("301_redirect\n", []), %% /301_redirect1 -> /redir (relative-url + append) Uri1 = "http://localhost:8000/301_redirect1/index.html", ?line {ok, "301", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), ?line "http://localhost:8000/redir/301_redirect1/index.html" = proplists:get_value("Location", Hdrs1), %% /301_redirect2 -> /redir (relative-url + noappend) Uri2 = "http://localhost:8000/301_redirect2/index.html", ?line {ok, "301", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line "http://localhost:8000/redir" = proplists:get_value("Location", Hdrs2), %% /301_redirect3 -> /redir (absolute-url + append) Uri3 = "http://localhost:8000/301_redirect3/index.html", ?line {ok, "301", Hdrs3, _} = ibrowse:send_req(Uri3, [], get), ?line "http://yaws.hyber.org/301_redirect3/index.html" = proplists:get_value("Location", Hdrs3), %% /301_redirect4 -> /redir (absolute-url + noappend) Uri4 = "http://localhost:8000/301_redirect4/index.html", ?line {ok, "301", Hdrs4, _} = ibrowse:send_req(Uri4, [], get), ?line "http://yaws.hyber.org/" = proplists:get_value("Location", Hdrs4), ok. test_404_redirect() -> io:format("404_redirect\n", []), Err404 = lists:flatten(["

404 ", yaws_api:code_to_phrase(404), "

"]), %% /404_redirect1 -> default content (append) Uri1 = "http://localhost:8000/404_redirect1/index.html", ?line {ok, "404", _, Body1} = ibrowse:send_req(Uri1, [], get), ?line Err404 = Body1, %% /404_redirect2 -> default content (noappend) Uri2 = "http://localhost:8000/404_redirect2/index.html", ?line {ok, "404", _, Body2} = ibrowse:send_req(Uri2, [], get), ?line Err404 = Body2, %% /404_redirect3 -> /error404.yaws (append) Uri3 = "http://localhost:8000/404_redirect3/index.html", ?line {ok, "404", _, Body3} = ibrowse:send_req(Uri3, [], get), ?line "/error404.yaws/404_redirect3/index.html\n" = Body3, %% /404_redirect4 -> /error404.yaws (noappend) Uri4 = "http://localhost:8000/404_redirect4/index.html", ?line {ok, "404", _, Body4} = ibrowse:send_req(Uri4, [], get), ?line "/error404.yaws\n" = Body4, ok. test_bad_redirect() -> io:format("bad_redirect\n", []), Env = #env{debug=false, trace=false, id="test", embedded=false}, ?line {error, _} = yaws_config:load(Env#env{conf={file, ?srcdir ++ "/bad_redirect1.conf"}}), ?line {error, _} = yaws_config:load(Env#env{conf={file, ?srcdir ++ "/bad_redirect2.conf"}}), ?line {error, _} = yaws_config:load(Env#env{conf={file, ?srcdir ++ "/bad_redirect3.conf"}}), ?line {error, _} = yaws_config:load(Env#env{conf={file, ?srcdir ++ "/bad_redirect4.conf"}}), ok. test_redirect_url_encode() -> io:format("test_redirect_url_encode\n", []), %% /redirect?url?encode1 -> /redir? (append) Uri1 = "http://localhost:8000/redirect%3Furl%3Fencode1/index.html", ?line {ok, "302", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), ?line "http://localhost:8000/redir%3F/redirect%3Furl%3Fencode1/index.html" = proplists:get_value("Location", Hdrs1), %% /redirect?url?encode2 -> /redir? (noappend) Uri2 = "http://localhost:8000/redirect%3Furl%3Fencode2/index.html", ?line {ok, "302", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line "http://localhost:8000/redir%3F" = proplists:get_value("Location", Hdrs2), ok. test_redirect_querystring() -> io:format("test_redirect_querystring\n", []), %% /default_redirect1 -> /redir (relative-url + append) Uri1 = "http://localhost:8000/default_redirect1/index.html?a=b&c=d", ?line {ok, "302", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), ?line "http://localhost:8000/redir/default_redirect1/index.html?a=b&c=d" = proplists:get_value("Location", Hdrs1), %% /default_redirect2 -> /redir (relative-url + noappend) Uri2 = "http://localhost:8000/default_redirect2/index.html?a=b&c=d", ?line {ok, "302", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line "http://localhost:8000/redir?a=b&c=d" = proplists:get_value("Location", Hdrs2), %% /default_redirect3 -> /redir (absolute-url + append) Uri3 = "http://localhost:8000/default_redirect3/index.html?a=b&c=d", ?line {ok, "302", Hdrs3, _} = ibrowse:send_req(Uri3, [], get), ?line "http://yaws.hyber.org/default_redirect3/index.html?a=b&c=d" = proplists:get_value("Location", Hdrs3), %% /default_redirect4 -> /redir (absolute-url + noappend) Uri4 = "http://localhost:8000/default_redirect4/index.html?a=b&c=d", ?line {ok, "302", Hdrs4, _} = ibrowse:send_req(Uri4, [], get), ?line "http://yaws.hyber.org/?a=b&c=d" = proplists:get_value("Location", Hdrs4), %% /404_redirect3 -> /error404.yaws (append) Uri5 = "http://localhost:8000/404_redirect3/index.html?a=b&c=d", ?line {ok, "404", _, Body5} = ibrowse:send_req(Uri5, [], get), ?line "/error404.yaws/404_redirect3/index.html?a=b&c=d\n" = Body5, %% /404_redirect4 -> /error404.yaws (noappend) Uri6 = "http://localhost:8000/404_redirect4/index.html?a=b&c=d", ?line {ok, "404", _, Body6} = ibrowse:send_req(Uri6, [], get), ?line "/error404.yaws?a=b&c=d\n" = Body6, ok. test_redirect_post() -> io:format("test_redirect_post\n", []), %% (partial_post_size = 5 / content-length = 11) Data = "foo=1&bar=2", Sz = length(Data), Hdrs = [{content_length, Sz}, {content_type, "application/x-www-form-urlencoded"}], %% Use the same connection for all requests {ok, ConnPid} = ibrowse:spawn_worker_process("localhost", 8000), %% Data must be flushed on redirect (here, trailing slash is added) Uri1 = "http://localhost:8000/test", ?line {ok, "302", Hdrs1, _} = ibrowse:send_req_direct(ConnPid, Uri1, Hdrs, post, Data, []), ?line Uri2 = proplists:get_value("Location", Hdrs1), ?line "http://localhost:8000/test/" = Uri2, ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri2, [], get), %% Data must be flushed on redirect (here, on configured redirect) Uri3 = "http://localhost:8000/post_redirect1", ?line {ok, "302", Hdrs3, _} = ibrowse:send_req_direct(ConnPid, Uri3, Hdrs, post, Data, []), ?line Uri4 = proplists:get_value("Location", Hdrs3), ?line "http://localhost:8000/test/index.yaws" = Uri4, ?line {ok, "200", _, _} = ibrowse:send_req_direct(ConnPid, Uri4, [], get), %% Data must be readable by /test/index.yaws Uri5 = "http://localhost:8000/post_redirect2", ?line {ok, "200", _, Body5} = ibrowse:send_req_direct(ConnPid, Uri5, Hdrs, post, Data, []), ?line Body5 = Data ++ "\n", ibrowse:stop_worker_process(ConnPid), ok. yaws-2.0.2/test/t9/www/0000775000175000017500000000000012605311413011634 500000000000000yaws-2.0.2/test/t9/www/test/0000775000175000017500000000000012605311413012613 500000000000000yaws-2.0.2/test/t9/www/test/index.yaws0000664000175000017500000000101312605311413014542 00000000000000 out(Arg) -> case Arg#arg.clidata of undefined -> {html, "no data"}; {partial, Bin} -> case Arg#arg.cont of undefined -> {get_more, [Bin], Arg#arg.state}; Cont -> {get_more, [Bin|Cont], Arg#arg.state} end; Bin -> case Arg#arg.cont of undefined -> {content, "text/plain", Bin}; Cont -> {content, "text/plain", lists:reverse([Bin|Cont])} end end. yaws-2.0.2/test/t9/www/error404.yaws0000664000175000017500000000016412605311413014043 00000000000000 out(Arg) -> {abs_path, Path} = (Arg#arg.req)#http_request.path, {content, "text/plain", Path}. yaws-2.0.2/test/t9/bad_redirect1.conf0000664000175000017500000000013612605311413014267 00000000000000 /bad_redirect = yaws-2.0.2/test/t9/yaws.conf.in0000664000175000017500000000251112605311413013166 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 port = 8000 listen = 0.0.0.0 listen_backlog = 512 deflate = false docroot = @abs_srcdir@/www partial_post_size = 5 /default_redirect1 = /redir /default_redirect2 == /redir /default_redirect3 = http://yaws.hyber.org /default_redirect4 == http://yaws.hyber.org /301_redirect1 = 301 /redir /301_redirect2 == 301 /redir /301_redirect3 = 301 http://yaws.hyber.org /301_redirect4 == 301 http://yaws.hyber.org /404_redirect1 = 404 /404_redirect2 == 404 /404_redirect3 = 404 /error404.yaws /404_redirect4 == 404 /error404.yaws "/redirect?url?encode1" = "/redir%3F" "/redirect?url?encode2" == "/redir%3F" /post_redirect1 == 302 /test/index.yaws /post_redirect2 == 200 /test/index.yaws yaws-2.0.2/test/t9/Makefile.am0000664000175000017500000000112712605311413012765 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl EXTRA_DIST = $(MODULES) bad_redirect1.conf bad_redirect2.conf bad_redirect3.conf bad_redirect4.conf www EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/t7/0000775000175000017500000000000012605312015011005 500000000000000yaws-2.0.2/test/t7/Makefile.in0000664000175000017500000003617512605311446013015 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t7 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl EXTRA_DIST = $(MODULES) mime.types EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t7/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t7/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t7/app_test.erl0000664000175000017500000001212012605311413013245 00000000000000-module(app_test). -compile(export_all). -include_lib("ibrowse/include/ibrowse.hrl"). -include("tftest.hrl"). %% Way to invoke just one test start([F]) -> ?line {ok, _} = ibrowse:start_link(), apply(app_test, F, []), ibrowse:stop(). start() -> io:format("\n ==== MIME-TYPES TESTS ==== \n\n", []), ?line {ok, _} = ibrowse:start_link(), test_generated_module(), test_default_type(), test_yaws_type(), test_erlang_type(), test_gzip_with_charset(), ibrowse:stop(). test_generated_module() -> io:format("generated_module_test\n", []), [_, Host] = string:tokens(atom_to_list(node()), "@"), Node = list_to_atom("test@" ++ Host), Vhost1 = {"localhost:8000", 8000}, Vhost2 = {"localhost:8001", 8001}, ?line CInfo = rpc:call(Node,mime_types,module_info,[compile]), ?line IdDir = rpc:call(Node,yaws,id_dir,[testid]), ?line IdDir = filename:dirname(proplists:get_value(source, CInfo)), ?line "text/html" = rpc:call(Node,mime_types,default_type,[]), ?line "text/html" = rpc:call(Node,mime_types,default_type,[global]), ?line "text/html" = rpc:call(Node,mime_types,default_type,[Vhost1]), ?line "text/plain; charset=UTF-8" = rpc:call(Node,mime_types,default_type,[Vhost2]), ?line {yaws, "text/html"} = rpc:call(Node,mime_types,t,["yaws"]), ?line {yaws, "text/html"} = rpc:call(Node,mime_types,t,[global,"yaws"]), ?line {yaws, "text/html"} = rpc:call(Node,mime_types,t,[Vhost1,"yaws"]), ?line {yaws, "text/xhtml; charset=ISO-8859-1"} = rpc:call(Node,mime_types,t,[Vhost2,"yaws"]), ?line {regular, "text/plain; charset=UTF-8"} = rpc:call(Node,mime_types,t,["tst"]), ?line {regular, "text/plain; charset=UTF-8"} = rpc:call(Node,mime_types,t,[global,"tst"]), ?line {regular, "text/plain; charset=UTF-8"} = rpc:call(Node,mime_types,t,[Vhost1,"tst"]), ?line {regular, "application/x-test; charset=US-ASCII"} = rpc:call(Node,mime_types,t,[Vhost2,"tst"]), ?line {regular, "text/html"} = rpc:call(Node,mime_types,t,["test"]), ?line {regular, "text/html"} = rpc:call(Node,mime_types,t,[global,"test"]), ?line {regular, "text/html"} = rpc:call(Node,mime_types,t,[Vhost1,"test"]), ?line {regular, "application/x-test; charset=UTF-8"} = rpc:call(Node,mime_types,t,[Vhost2,"test"]), ?line {php, "text/html"} = rpc:call(Node,mime_types,t,["php"]), ?line {php, "text/html"} = rpc:call(Node,mime_types,t,[global, "php"]), ?line {php, "text/html"} = rpc:call(Node,mime_types,t,[Vhost1, "php"]), ?line {php, "application/x-httpd-php"} = rpc:call(Node,mime_types,t,[Vhost2,"php"]), ?line {php, "application/x-httpd-php"} = rpc:call(Node,mime_types,t,[Vhost2,"PHP"]), ?line {regular, "php5", "application/x-httpd-php5"} = rpc:call(Node,mime_types,revt,[Vhost2,"5php"]), ?line {regular, "PHP5", "application/x-httpd-php5"} = rpc:call(Node,mime_types,revt,[Vhost2,"5PHP"]), ?line {regular, "text/plain"} = rpc:call(Node,mime_types,t,["html"]), ?line {regular, "text/plain"} = rpc:call(Node,mime_types,t,[global,"html"]), ?line {regular, "text/plain"} = rpc:call(Node,mime_types,t,[Vhost1,"html"]), ?line {regular, "text/plain; charset=UTF-8"} = rpc:call(Node,mime_types,t,[Vhost2,"html"]), ok. test_default_type() -> io:format("default_type_test\n", []), Uri1 = "http://localhost:8000/news", Uri2 = "http://localhost:8001/news", ?line {ok, "200", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), ?line {ok, "200", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line "text/html" = proplists:get_value("Content-Type", Hdrs1), ?line "text/plain; charset=UTF-8" = proplists:get_value("Content-Type", Hdrs2), ok. test_yaws_type() -> io:format("yaws_type_test\n", []), Uri1 = "http://localhost:8000/index.yaws", Uri2 = "http://localhost:8001/index.yaws", ?line {ok, "200", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), ?line {ok, "200", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line "text/html" = proplists:get_value("Content-Type", Hdrs1), ?line "text/xhtml; charset=ISO-8859-1" = proplists:get_value("Content-Type", Hdrs2), ok. test_erlang_type() -> io:format("erlang_type_test\n", []), Uri1 = "http://localhost:8000/code/myappmod.erl", Uri2 = "http://localhost:8001/code/myappmod.erl", ?line {ok, "200", Hdrs1, _} = ibrowse:send_req(Uri1, [], get), ?line {ok, "200", Hdrs2, _} = ibrowse:send_req(Uri2, [], get), ?line "text/html" = proplists:get_value("Content-Type", Hdrs1), ?line "text/x-erlang; charset=UTF-8" = proplists:get_value("Content-Type", Hdrs2), ok. test_gzip_with_charset() -> io:format("test_gzip_with_charset\n", []), Uri = "http://localhost:8001/index.yaws", ?line {ok, "200", Hdrs, _} = ibrowse:send_req(Uri, [{"Accept-Encoding", "gzip, deflate"}], get), ?line "text/xhtml; charset=ISO-8859-1" = proplists:get_value("Content-Type", Hdrs), ?line "gzip" = proplists:get_value("Content-Encoding", Hdrs), ok. yaws-2.0.2/test/t7/mime.types0000664000175000017500000000015512605311413012744 00000000000000text/x-erlang erl application/x-httpd-php php application/x-httpd-php5 php5 yaws-2.0.2/test/t7/yaws.conf.in0000664000175000017500000000177212605311413013174 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 default_type = text/html add_types = add_charsets = port = 8000 listen = 0.0.0.0 deflate = true docroot = @abs_top_srcdir@/www port = 8001 listen = 0.0.0.0 deflate = true docroot = @abs_top_srcdir@/www default_type = text/plain mime_types_file = @abs_srcdir@/mime.types add_types = default_charset = UTF-8 add_charsets = yaws-2.0.2/test/t7/Makefile.am0000664000175000017500000000102212605311413012755 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl EXTRA_DIST = $(MODULES) mime.types EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/t12/0000775000175000017500000000000012605312015011061 500000000000000yaws-2.0.2/test/t12/Makefile.in0000664000175000017500000003621212605311446013061 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = test/t12 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = app_test.erl EXTRA_DIST = $(MODULES) invalid-dhparams.pem EBIN_FILES = $(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) YAWS_CONF = yaws.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/t12/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/t12/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws.conf: $(top_builddir)/config.status $(srcdir)/yaws.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/test/t12/invalid-dhparams.pem0000664000175000017500000000007212605311413014727 00000000000000-----BEGIN DH PARAMETERS----- -----END DH PARAMETERS----- yaws-2.0.2/test/t12/app_test.erl0000664000175000017500000000412512605311413013327 00000000000000-module(app_test). -compile(export_all). -include("yaws.hrl"). -include_lib("ibrowse/include/ibrowse.hrl"). -include("tftest.hrl"). %% Way to invoke just one test start([F]) -> ?line {ok, _} = ibrowse:start_link(), apply(app_test, F, []), ibrowse:stop(). start() -> io:format("\n ==== DHFILE TESTS ==== \n\n", []), ?line {ok, _} = ibrowse:start_link(), test_ssl_with_valid_dhfile(), test_ssl_with_invalid_dhfile(), ibrowse:stop(). start_ssl() -> ok = application:start(crypto), ok = application:start(asn1), ok = application:start(public_key), ok = application:start(ssl), ok. stop_ssl() -> ok = application:stop(ssl), ok = application:stop(public_key), ok = application:stop(asn1), ok = application:stop(crypto), ok. test_ssl_with_valid_dhfile() -> io:format("ssl with valid dhfile\n", []), start_ssl(), %% The server has its own Diffie-Hellman group. Try connecting %% with ephemeral DH and see if it works. Uri = "https://localhost:8443/index.yaws", Options = [ {is_ssl, true} , {ssl_options, [ {verify, 0} , {ciphers, [C || {dhe_rsa, _, _}=C <- ssl:cipher_suites()]} ] } ], ?line {ok, "200", _, _} = ibrowse:send_req(Uri, [], post, <<>>, Options), stop_ssl(). test_ssl_with_invalid_dhfile() -> io:format("ssl with invalid dhfile\n", []), start_ssl(), %% ssl:listen/2 succeeds even when an invalid dhfile is given, and %% then fails on ssl:ssl_accept/2. This sounds like a bug in %% ssl:listen/2 but that's how it works anyway. Uri = "https://localhost:8444/index.yaws", Options = [ {is_ssl, true} , {ssl_options, [ {verify, 0} , {ciphers, [C || {dhe_rsa, _, _}=C <- ssl:cipher_suites()]} ] } ], ?line {error, {conn_failed, _}} = ibrowse:send_req(Uri, [], post, <<>>, Options), stop_ssl(). yaws-2.0.2/test/t12/yaws.conf.in0000664000175000017500000000210312605311413013235 00000000000000logdir = @abs_builddir@/logs ebin_dir = @abs_top_builddir@/test/ibrowse/ebin trace = false copy_error_log = true log_wrap_size = 1000000 log_resolve_hostname = false fail_on_bind_err = true pick_first_virthost_on_nomatch = true use_fdsrv = false keepalive_timeout = 10000 port = 8443 listen = 0.0.0.0 docroot = @abs_top_srcdir@/www keyfile = @abs_top_srcdir@/ssl/yaws-key.pem certfile = @abs_top_srcdir@/ssl/yaws-cert.pem dhfile = @abs_top_srcdir@/ssl/dhparams.pem depth = 0 port = 8444 listen = 0.0.0.0 docroot = @abs_top_srcdir@/www keyfile = @abs_top_srcdir@/ssl/yaws-key.pem certfile = @abs_top_srcdir@/ssl/yaws-cert.pem dhfile = @abs_srcdir@/invalid-dhparams.pem depth = 0 yaws-2.0.2/test/t12/Makefile.am0000664000175000017500000000103412605311413013034 00000000000000include @top_srcdir@/include.mk MODULES = app_test.erl EXTRA_DIST = $(MODULES) invalid-dhparams.pem EBIN_FILES=$(MODULES:%.erl=%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk include @top_srcdir@/test/support/include.mk YAWS_CONF=yaws.conf all-local: clean-local: clean-test $(AM_V_at)rm -f $(EBIN_FILES) check-local: $(EBIN_FILES) app-test distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/test/Makefile.am0000664000175000017500000000102212605311413012423 00000000000000EXTRA_DIST = README include/tftest.hrl support/include.mk if !MINGW SUBDIRS = src eunit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 include @srcdir@/support/include.mk ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -pa $(top_builddir)/test/ibrowse ERL_FLAGS = $(ERL_GENERIC_FLAGS) all-local: clean-local: $(AM_V_at)rm -rf ibrowse bin logs test: check else check-local: @echo @echo " SKIPPED - Tests cannot be executed when Yaws is cross-compiled" @echo test: check endif # Local Variables: # tab-width: 8 # End: yaws-2.0.2/rebar.config.script0000664000175000017500000001345012605311412013204 00000000000000%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ft=erlang ts=4 sw=4 et UpdateDeps = fun(Config, NewDeps) -> case lists:keyfind(deps, 1, Config) of {deps, Deps} -> NDeps = Deps ++ NewDeps, lists:keyreplace(deps, 1, Config, {deps, NDeps}); false -> Config ++ [{deps, NewDeps}] end end, Dir = filename:dirname(SCRIPT), ErtsVsn = case string:tokens(erlang:system_info(version), ".") of [A,B] -> {list_to_integer(A), list_to_integer(B), 0}; [A,B,C|_] -> {list_to_integer(A), list_to_integer(B), list_to_integer(C)} end. %% generate a default test/t11/include/srcdir_test.hrl file so rebar can %% compile the tests ok = filelib:ensure_dir(filename:join(Dir, "test/t11/include/srcdir_test.hrl")), ok = file:write_file(filename:join(Dir, "test/t11/include/srcdir_test.hrl"), <<"-define(SRCDIR_VERSION, \"1.0\").\n">>), %% generate a charset include file ok = file:write_file(filename:join(Dir, "src/yaws_charset.hrl"), case os:getenv("YAWS_CHARSET") of false -> <<"-define(YAWS_CHARSET, undefined).\n">>; Charset -> [<<"-define(YAWS_CHARSET, \"">>, Charset, <<"\").\n">>] end), SoapDeps = [{erlsom, ".*", {git, "git://github.com/willemdj/erlsom.git", {branch, "master"}}}, {xmlrpc, ".*", {git, "git://github.com/rwbr/exmlrpc.git", {branch, "master"}}}], Cfg0 = case os:getenv("YAWS_SOAP") of false -> CONFIG; _ -> UpdateDeps(CONFIG, SoapDeps) end, ErlOpts0 = case lists:keyfind(erl_opts, 1, Cfg0) of {erl_opts, EOpts} -> EOpts; false -> [] end, PortEnv0 = case lists:keyfind(port_env, 1, Cfg0) of {port_env, PEnv} -> PEnv; false -> [] end, PortSpecs0 = case lists:keyfind(port_specs, 1, Cfg0) of {port_specs, PSpecs} -> case os:getenv("YAWS_DISABLE_PAM") of false -> PSpecs; _ -> lists:keydelete("priv/lib/epam.so", 1, PSpecs) end; false -> [] end, %% yaws:sendfile/5 was buggy in R15B (ERTS = 5.9) code:ensure_loaded(file), ErlOpts1 = case erlang:function_exported(file,sendfile,5) of true when ErtsVsn >= {5,9,1} -> ErlOpts0 ++ [{d,'HAVE_ERLANG_SENDFILE'}]; _ -> ErlOpts0 end, code:ensure_loaded(crypto), ErlOpts2 = case erlang:function_exported(crypto,hash,2) of true -> ErlOpts1 ++ [{d,'HAVE_CRYPTO_HASH'}]; false -> ErlOpts1 end, code:ensure_loaded(inet), ErlOpts3 = case erlang:function_exported(inet,parse_strict_address,1) of true -> ErlOpts2 ++ [{d,'HAVE_INET_PARSE_STRICT_ADDRESS'}]; false -> ErlOpts2 end, %% Unicode module was buggy for R14B04 and previous (ERTS <= 5.8.5) ErlOpts4 = if ErtsVsn =< {5,8,3} -> ErlOpts3 ++ [{d,'HAVE_BAD_UNICODE'}]; true -> ErlOpts3 end, %% filelib:wildcard/2 was buggy for R15B03 and previous (ERTS <= 5.9.3) ErlOpts5 = if ErtsVsn =< {5,9,3} -> ErlOpts4 ++ [{d,'HAVE_BAD_WILDCARD'}]; true -> ErlOpts4 end, %% Check for support of honor_cipher_order SSL option (ERTS >= 6.0) ErlOpts6 = if ErtsVsn >= {6,0,0} -> ErlOpts5 ++ [{d,'HAVE_SSL_HONOR_CIPHER_ORDER'}]; true -> ErlOpts5 end, %% Check for support of client_renegotiation SSL option (ERTS >= 7.0) ErlOpts7 = if ErtsVsn >= {7,0,0} -> ErlOpts6 ++ [{d,'HAVE_SSL_CLIENT_RENEGOTIATION'}]; true -> ErlOpts6 end, %% Check for support of log_alert SSL option (ERTS >= 5.10.3) ErlOpts8 = if ErtsVsn >= {5,10,3} -> ErlOpts7 ++ [{d,'HAVE_LOG_ALERT'}]; true -> ErlOpts7 end, %% Check for erlang:now/0 ErlOpts9 = if ErtsVsn < {7,0,0} -> ErlOpts8 ++ [{d,'HAVE_ERLANG_NOW'}]; true -> ErlOpts8 end, ErlOpts = ErlOpts9, HaveSendFile = lists:keymember('HAVE_SENDFILE', 3, ErlOpts), {PortEnv1, PortSpecs1} = if HaveSendFile -> {PortEnv0 ++ [{"DRV_CFLAGS", "$DRV_CFLAGS -DHAVE_SENDFILE"}], PortSpecs0 ++ [{"priv/lib/yaws_sendfile_drv.so", ["c_src/yaws_sendfile_drv.c", "c_src/hashtable.c"]}]}; true -> {PortEnv0, PortSpecs0} end, Cfg1 = lists:keyreplace(erl_opts, 1, Cfg0, {erl_opts, ErlOpts}), Cfg2 = lists:keyreplace(port_env, 1, Cfg1, {port_env, PortEnv1}), Cfg3 = lists:keyreplace(port_specs, 1, Cfg2, {port_specs, PortSpecs1}), %% Check for the existence of a .rebar/YAWS_DEV_MODE file, and if found, %% add ibrowse as a dependency since it's used for testing. This avoids the %% need to specify ibrowse as a regular dependency, which is beneficial for %% projects that depend on Yaws as they don't need the ibrowse dependency. DevModeFile = filename:join([Dir, ".rebar", "YAWS_DEV_MODE"]), IbrowseDep = {ibrowse, ".*", {git,"git://github.com/cmullaparthi/ibrowse.git", {tag,"v3.0.4"}}}, Cfg4 = case filelib:is_file(DevModeFile) of true -> UpdateDeps(Cfg3, [IbrowseDep]); false -> Cfg3 end, Cfg4. yaws-2.0.2/include.mk0000664000175000017500000000247712605311412011402 00000000000000AM_V_ERLC = $(am__v_ERLC_$(V)) am__v_ERLC_ = $(am__v_ERLC_$(AM_DEFAULT_VERBOSITY)) am__v_ERLC_0 = @echo " ERLC " $@; am__v_ERLC_1 = ERLC_GENERIC_FLAGS = -Werror +debug_info $(DEBUG_ERLC_FLAGS) \ -pa $(top_srcdir) -pa $(top_builddir) -pa $(top_builddir)/ebin \ -I $(top_srcdir)/include -I $(srcdir)/../include \ -I $(top_builddir)/include -I $(builddir)/../include ifeq ($(HAVE_SENDFILE),true) ERLC_GENERIC_FLAGS += -DHAVE_SENDFILE endif ifeq ($(HAVE_ERLANG_SENDFILE),true) ERLC_GENERIC_FLAGS += -DHAVE_ERLANG_SENDFILE endif ifeq ($(HAVE_CRYPTO_HASH),true) ERLC_GENERIC_FLAGS += -DHAVE_CRYPTO_HASH endif ifeq ($(HAVE_INET_PARSE_STRICT_ADDRESS),true) ERLC_GENERIC_FLAGS += -DHAVE_INET_PARSE_STRICT_ADDRESS endif ifeq ($(HAVE_BAD_UNICODE),true) ERLC_GENERIC_FLAGS += -DHAVE_BAD_UNICODE endif ifeq ($(HAVE_BAD_WILDCARD),true) ERLC_GENERIC_FLAGS += -DHAVE_BAD_WILDCARD endif ifeq ($(HAVE_SSL_HONOR_CIPHER_ORDER),true) ERLC_GENERIC_FLAGS += -DHAVE_SSL_HONOR_CIPHER_ORDER endif ifeq ($(HAVE_SSL_CLIENT_RENEGOTIATION),true) ERLC_GENERIC_FLAGS += -DHAVE_SSL_CLIENT_RENEGOTIATION endif ifeq ($(HAVE_SSL_LOG_ALERT),true) ERLC_GENERIC_FLAGS += -DHAVE_SSL_LOG_ALERT endif ifeq ($(HAVE_ERLANG_NOW),true) ERLC_GENERIC_FLAGS += -DHAVE_ERLANG_NOW endif # Local Variables: # tab-width: 8 # End: yaws-2.0.2/ebin/0000775000175000017500000000000012605312014010410 500000000000000yaws-2.0.2/ebin/Makefile.in0000664000175000017500000004131312605311445012406 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = ebin DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(beamdir)" DATA = $(beam_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ beamdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/ebin APP_FILES = yaws.app yaws.appup BEAM_FILES = *.beam beam_DATA = $(APP_FILES) $(BEAM_FILES) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ebin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign ebin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-beamDATA: $(beam_DATA) @$(NORMAL_INSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(beamdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(beamdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(beamdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(beamdir)" || exit $$?; \ done uninstall-beamDATA: @$(NORMAL_UNINSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(beamdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(beamdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-beamDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-beamDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-beamDATA install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-beamDATA clean-local: $(AM_V_at)rm -f $(APP_FILES) $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/ebin/Makefile.am0000664000175000017500000000036312605311412012367 00000000000000beamdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/ebin APP_FILES = yaws.app yaws.appup BEAM_FILES = *.beam beam_DATA = $(APP_FILES) $(BEAM_FILES) clean-local: $(AM_V_at)rm -f $(APP_FILES) $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: yaws-2.0.2/m4/0000775000175000017500000000000012605312014010013 500000000000000yaws-2.0.2/m4/libtool.m40000644000175000017500000106011112605311443011644 00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file 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. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS yaws-2.0.2/m4/ax_compare_version.m40000664000175000017500000000663512605311412014073 00000000000000dnl Macro to compare version numbers in configure. dnl AC_DEFUN([AX_COMPARE_VERSION], [ # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. AS_VAR_PUSHDEF([A],[ax_compare_version_A]) A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/[[^0-9]]//g'` AS_VAR_PUSHDEF([B],[ax_compare_version_B]) B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/[[^0-9]]//g'` dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary dnl # then the first line is used to determine if the condition is true. dnl # The sed right after the echo is to remove any indented white space. m4_case(m4_tolower($2), [lt],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` ], [gt],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` ], [le],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` ], [ge],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` ],[ dnl Split the operator from the subversion count if present. m4_bmatch(m4_substr($2,2), [0],[ # A count of zero means use the length of the shorter version. # Determine the number of characters in A and B. ax_compare_version_len_A=`echo "$A" | awk '{print(length)}'` ax_compare_version_len_B=`echo "$B" | awk '{print(length)}'` # Set A to no more than B's length and B to no more than A's length. A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` ], [[0-9]+],[ # A count greater than zero means use only that many subversions A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` ], [.+],[ AC_WARNING( [illegal OP numeric parameter: $2]) ],[]) # Pad zeros at end of numbers to make same length. ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" B="$B`echo $A | sed 's/./0/g'`" A="$ax_compare_version_tmp_A" # Check for equality or inequality as necessary. m4_case(m4_tolower(m4_substr($2,0,2)), [eq],[ test "x$A" = "x$B" && ax_compare_version=true ], [ne],[ test "x$A" != "x$B" && ax_compare_version=true ],[ AC_WARNING([illegal OP parameter: $2]) ]) ]) AS_VAR_POPDEF([A])dnl AS_VAR_POPDEF([B])dnl dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. if test "$ax_compare_version" = "true" ; then m4_ifvaln([$4],[$4],[:])dnl m4_ifvaln([$5],[else $5])dnl fi ]) dnl AX_COMPARE_VERSION yaws-2.0.2/m4/ltversion.m40000644000175000017500000000126212605311443012226 00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file 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. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) yaws-2.0.2/m4/ltoptions.m40000644000175000017500000003007312605311443012236 00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file 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. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) yaws-2.0.2/m4/ltsugar.m40000644000175000017500000001042412605311443011662 00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file 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. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) yaws-2.0.2/m4/erlang.m40000664000175000017500000000373112605311412011452 00000000000000dnl dnl More functions to query Erlang environment. dnl dnl ERLANG_CHECK_ERTS([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) dnl Substitudes dnl ERLANG_ERTS_DIR dnl ERLANG_ERTS_VER AC_DEFUN([ERLANG_CHECK_ERTS], [ AC_REQUIRE([AC_ERLANG_PATH_ERLC])[]dnl AC_REQUIRE([AC_ERLANG_PATH_ERL])[]dnl AC_REQUIRE([AC_ERLANG_SUBST_ROOT_DIR])[]dnl AC_CACHE_CHECK([for Erlang/OTP ERTS version], [erlang_cv_erts_ver], [ AC_LANG_PUSH(Erlang)[]dnl AC_RUN_IFELSE( [AC_LANG_PROGRAM([], [dnl file:write_file("conftest.out", erlang:system_info(version)), halt(0)])], [erlang_cv_erts_ver=`cat conftest.out`], [if test ! -f conftest.out; then AC_MSG_FAILURE([test Erlang program execution failed]) else erlang_cv_erts_ver="not found" fi]) AC_LANG_POP(Erlang)[]dnl ]) AC_CACHE_CHECK([for Erlang/OTP ERTS directory], [erlang_cv_erts_dir], [ erlang_cv_erts_dir="${ERLANG_ROOT_DIR}/erts-$erlang_cv_erts_ver" if test ! -d "$erlang_cv_erts_dir"; then erlang_cv_erts_dir="${ERLANG_ROOT_DIR}/usr" fi ]) AC_SUBST([ERLANG_ERTS_DIR], [$erlang_cv_erts_dir]) AC_SUBST([ERLANG_ERTS_VER], [$erlang_cv_erts_ver]) AS_IF([test "$erlang_cv_erts_ver" = "not found"], [$2], [$1]) ]) dnl ERLANG_CHECK_RELEASE() dnl Substitudes dnl ERLANG_RELEASE AC_DEFUN([ERLANG_CHECK_RELEASE], [ AC_REQUIRE([AC_ERLANG_PATH_ERLC])[]dnl AC_REQUIRE([AC_ERLANG_PATH_ERL])[]dnl AC_REQUIRE([AC_ERLANG_SUBST_ROOT_DIR])[]dnl AC_CACHE_CHECK([for Erlang/OTP release], [erlang_cv_release], [ AC_LANG_PUSH(Erlang)[]dnl AC_RUN_IFELSE( [AC_LANG_PROGRAM([], [dnl file:write_file("conftest.out", erlang:system_info(otp_release)), halt(0)])], [erlang_cv_release=`cat conftest.out`], [if test ! -f conftest.out; then AC_MSG_FAILURE([test Erlang program execution failed]) else erlang_cv_release="not found" fi]) AC_LANG_POP(Erlang)[]dnl ]) AC_SUBST([ERLANG_RELEASE], [$erlang_cv_release]) ]) yaws-2.0.2/m4/lt~obsolete.m40000644000175000017500000001375612605311443012566 00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file 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. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) yaws-2.0.2/m4/colored-echo.m40000664000175000017500000000424412605311412012545 00000000000000dnl dnl Macro to output bold and colored text. dnl dnl COLORED_ECHO_INIT dnl This macro must be called first to initialize a context. AC_DEFUN([COLORED_ECHO_INIT], [ dnl Prepare fancy console output, taken from GNU shtools. colored_echo_bold='' colored_echo_norm='' AC_PROG_AWK if test x"$AWK" = x"not found"; then return fi case $TERM in xterm|xterm*|vt220|vt220*) dnl For the most important terminal types we directly know the dnl sequences. colored_echo_bold=`$AWK 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' /dev/null` colored_echo_norm=`$AWK 'BEGIN { printf("%c%c%c", 27, 91, 109); }' /dev/null` ;; vt100|vt100*|cygwin) colored_echo_bold=`$AWK 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' /dev/null` colored_echo_norm=`$AWK 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' /dev/null` ;; *) dnl For all others, we try to use a possibly existing `tput' or dnl `tcout' utility. paths=`$ECHO $PATH | sed -e 's/:/ /g'` for tool in tput tcout; do for dir in $paths; do if test -r "$dir/$tool" ; then for seq in bold md smso; do bold="`$dir/$tool $seq 2>/dev/null`" if test ".$bold" != . ; then colored_echo_bold="$bold" break fi done if test ".$colored_echo_bold" != . ; then for seq in sgr0 me rmso init reset; do norm="`$dir/$tool $seq 2>/dev/null`" if test ".$norm" != . ; then colored_echo_norm="$norm" break fi done fi break fi done if test x"$colored_echo_bold" != "x" -a x"$colored_echo_norm" != "x"; then break; fi done ;; esac ]) dnl COLORED_ECHO(TEXT) dnl Output text with: dnl o everything between %B and %b displayed bold. AC_DEFUN([COLORED_ECHO], [ text=`$ECHO $seo "$1" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec "$1" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` _AS_ECHO_LOG($text) ]) yaws-2.0.2/yaws.pc.in0000664000175000017500000000045412605311413011334 00000000000000## ## yaws.pc: pkg-config(1) specification ## prefix=@prefix@ exec_prefix=${prefix} libdir=${exec_prefix}/lib/yaws/ebin includedir=${prefix}/lib/yaws/include Name: yaws Description: Yet Another Web Server Version: @YAWS_VSN@ URL: http://yaws.hyber.org/ Libs: -pa ${libdir} Cflags: -I${includedir} yaws-2.0.2/src/0000775000175000017500000000000012605312014010262 500000000000000yaws-2.0.2/src/yaws_sendfile.erl0000664000175000017500000002030312605311412013541 00000000000000%%% File : yaws_sendfile.erl %%% Author : Steve Vinoski %%% Description : interface to sendfile linked-in driver for Yaws %%% Created : 9 Nov 2008 by Steve Vinoski -module(yaws_sendfile). -author('vinoski@ieee.org'). -include("../include/yaws.hrl"). -include_lib("kernel/include/file.hrl"). -export([send/2, send/3, send/4]). -export([have_sendfile/0, have_erlang_sendfile/0, check_gc_flags/1]). %% export bytes_to_transfer to avoid warning when sendfile is disabled (or not %% supported) -export([bytes_to_transfer/3]). -ifdef(HAVE_SENDFILE). -behavior(gen_server). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([start_link/0, stop/0]). have_sendfile() -> true. -else. have_sendfile() -> false. -endif. -ifdef(HAVE_ERLANG_SENDFILE). have_erlang_sendfile() -> true. -else. have_erlang_sendfile() -> false. -endif. check_gc_flags(GC) -> %% below, ignore dialyzer warning: %% The pattern depends on the macro HAVE_ERLANG_SENDFILE case have_erlang_sendfile() of false when ?gc_use_erlang_sendfile(GC) -> error_logger:error_msg("Cannot use file:sendfile/5: not supported, " "gen_tcp:send/2 will be used instead.~n", []); _ -> ok end, %% below, ignore dialyzer warning: %% The pattern depends on the macro HAVE_SENDFILE case have_sendfile() of false when ?gc_use_yaws_sendfile(GC) -> error_logger:error_msg("Cannot use Yaws sendfile linked-in driver:" " not supported, gen_tcp:send/2 will be used" " instead.~n", []); _ -> ok end. send(Out, Filename) -> send(Out, Filename, 0, all). send(Out, Filename, Offset) -> send(Out, Filename, Offset, all). send(Out, Filename, Offset, Count) -> GC = get(gc), ChunkSize = GC#gconf.large_file_chunk_size, ErlangSendFile = ?gc_use_erlang_sendfile(GC), YawsSendFile = ?gc_use_yaws_sendfile(GC), if ErlangSendFile -> erlang_sendfile(Out, Filename, Offset, Count, ChunkSize); YawsSendFile -> yaws_sendfile(Out, Filename, Offset, Count, ChunkSize); true -> compat_send(Out, Filename, Offset, Count, ChunkSize) end. bytes_to_transfer(Filename, Offset, Count) -> case Count of all -> case file:read_file_info(Filename) of {ok, #file_info{size = Size}} -> Size - Offset; Error -> Error end; Count when is_integer(Count) -> Count; _ -> {error, badarg} end. -ifdef(HAVE_ERLANG_SENDFILE). erlang_sendfile(Out, Filename, Offset, Count, ChunkSize) -> Count1 = bytes_to_transfer(Filename, Offset, Count), case Count1 of {error, _}=Error1 -> Error1; _ -> case file:open(Filename, [raw, read, binary]) of {ok, RawFile} -> Res = file:sendfile(RawFile, Out, Offset, Count1, [{chunk_size, ChunkSize}]), ok = file:close(RawFile), Res; Error2 -> Error2 end end. -else. erlang_sendfile(Out, Filename, Offset, Count, ChunkSize) -> compat_send(Out, Filename, Offset, Count, ChunkSize). -endif. -ifdef(HAVE_SENDFILE). yaws_sendfile(Out, Filename, Offset, Count, ChunkSize) -> Count1 = bytes_to_transfer(Filename, Offset, Count), case Count1 of {error, _}=Error -> Error; _ -> case prim_inet:getfd(Out) of {ok, SocketFd} -> do_send(Out, SocketFd, Filename, Offset, Count1, ChunkSize); Error2 -> Error2 end end. -record(state, { port, % driver port caller_tbl % table mapping socket fd to caller }). start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). stop() -> gen_server:cast(?MODULE, stop). init([]) -> process_flag(trap_exit, true), Shlib = "yaws_sendfile_drv", Dir = filename:join(yaws:get_priv_dir(), "lib"), case erl_ddll:load_driver(Dir, Shlib) of ok -> ok; {error, already_loaded} -> ok; _ -> exit({error, "could not load driver " ++ Shlib}) end, Port = open_port({spawn, Shlib}, [binary]), CallerTable = ets:new(yaws_sendfile, []), {ok, #state{port = Port, caller_tbl = CallerTable}}. handle_call({send, SocketFd, Msg}, From, State) -> true = erlang:port_command(State#state.port, Msg), true = ets:insert(State#state.caller_tbl, {SocketFd, From}), {noreply, State}; handle_call(_Req, _From, State) -> {reply, ok, State}. handle_info({_, {data, <>}}, State) -> Reply = case Res of 1 -> {ok, Cnt}; 0 -> {error, list_to_atom( lists:takewhile(fun(El) -> El =/= 0 end, binary_to_list(Err)))} end, CallerTable = State#state.caller_tbl, [{SocketFd, From}] = ets:lookup(CallerTable, SocketFd), gen_server:reply(From, Reply), ets:delete(CallerTable, SocketFd), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. handle_cast(stop, State) -> {stop, State}; handle_cast(_, State) -> {noreply, State}. terminate(_Reason, #state{port = Port, caller_tbl = CallerTable}) -> erlang:port_close(Port), receive {'EXIT', Port, _Reason} -> ok after 0 -> ok end, ets:delete(CallerTable), ok. code_change(_OldVsn, Data, _Extra) -> {ok, Data}. do_send(_Out, _SocketFd, _Filename, _Offset, Count, _) when Count =< 0 -> {ok, 0}; do_send(Out, SocketFd, Filename0, Offset, Count, ChunkSize) -> Filename = case file:native_name_encoding() of latin1 -> Filename0; utf8 -> unicode:characters_to_binary(Filename0) end, Call = list_to_binary([<>, Filename, <<0:8>>]), case gen_server:call(?MODULE, {send, SocketFd, Call}, infinity) of {error, eoverflow} -> compat_send(Out, Filename, Offset, Count, ChunkSize); Else -> Else end. -else. yaws_sendfile(Out, Filename, Offset, Count, ChunkSize) -> compat_send(Out, Filename, Offset, Count, ChunkSize). -endif. compat_send(Out, Filename, Offset, Count0, ChunkSize) -> Count = case Count0 of 0 -> all; _ -> Count0 end, case file:open(Filename, [read, binary, raw]) of {ok, Fd} -> file:position(Fd, {bof, Offset}), Ret = loop_send(Fd, ChunkSize, file:read(Fd, ChunkSize), Out, Count, 0), file:close(Fd), Ret; Err -> Err end. loop_send(Fd, ChunkSize, {ok, Bin}, Out, all, BytesSent) -> case gen_tcp:send(Out, Bin) of ok -> loop_send(Fd, ChunkSize, file:read(Fd, ChunkSize), Out, all, BytesSent+size(Bin)); Err -> Err end; loop_send(_Fd, _ChunkSize, eof, _Out, _, BytesSent) -> {ok, BytesSent}; loop_send(Fd, ChunkSize, {ok, Bin}, Out, Count, BytesSent) -> Sz = size(Bin), if Sz < Count -> case gen_tcp:send(Out, Bin) of ok -> loop_send(Fd, ChunkSize, file:read(Fd, ChunkSize), Out, Count-Sz, BytesSent+Sz); Err -> Err end; Sz == Count -> case gen_tcp:send(Out, Bin) of ok -> {ok, BytesSent+Sz}; Err -> Err end; Sz > Count -> <> = Bin, case gen_tcp:send(Out, Deliver) of ok -> {ok, BytesSent+Count}; Err -> Err end end; loop_send(_Fd, _, Err, _, _, _) -> Err. yaws-2.0.2/src/Makefile.in0000664000175000017500000004474012605311446012270 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/yaws_charset.hrl.in $(srcdir)/yaws_appdeps.hrl.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = yaws_charset.hrl yaws_appdeps.hrl CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ STATIC_MODULES = yaws.erl \ yaws_app.erl \ yaws_ticker.erl \ yaws_config.erl \ yaws_server.erl \ yaws_sup.erl \ yaws_api.erl \ yaws_log.erl \ yaws_trace.erl \ yaws_logger.erl \ yaws_ls.erl \ yaws_debug.erl \ yaws_compile.erl \ yaws_ctl.erl \ yaws_cgi.erl \ yaws_zlib.erl \ mime_type_c.erl \ yaws_session_server.erl \ yaws_outmod.erl \ yaws_revproxy.erl \ yaws_html.erl \ yaws_log_file_h.erl \ yaws_rss.erl \ yaws_appmod_dav.erl \ yaws_runmod_lock.erl \ yaws_pam.erl \ json.erl \ json2.erl \ jsonrpc.erl \ yaws_jsonrpc.erl \ yaws_xmlrpc.erl \ haxe.erl \ yaws_rpc.erl \ yaws_soap_srv.erl \ yaws_soap_lib.erl \ yaws_soap12_lib.erl \ yaws_appmod_cgi.erl \ yaws_appmod_fcgi.erl \ yaws_sendfile.erl \ yaws_sup_restarts.erl \ yaws_stats.erl \ yaws_vdir.erl \ yaws_multipart.erl \ yaws_shaper.erl \ yaws_dime.erl \ yaws_exhtml.erl \ yaws_sse.erl \ yaws_websockets.erl EXTRA_DIST = $(STATIC_MODULES) yaws_websockets.erl yaws_debug.hrl \ yaws_generated.template yaws.app.src yaws.app.src.script \ yaws.appup.src GENERATED_MODULES = yaws_generated.erl mime_types.erl MODULES = $(STATIC_MODULES) $(GENERATED_MODULES) EBIN_DIR = @top_builddir@/ebin EBIN_FILES = $(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): yaws_charset.hrl: $(top_builddir)/config.status $(srcdir)/yaws_charset.hrl.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ yaws_appdeps.hrl: $(top_builddir)/config.status $(srcdir)/yaws_appdeps.hrl.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_DIR)/yaws.app $(EBIN_DIR)/yaws.appup $(EBIN_FILES) tags: $(EBIN_DIR)/yaws_generated.beam $(EBIN_DIR)/yaws_debug.beam $(AM_V_GEN)erl -noshell -pa $(EBIN_DIR) -s yaws_debug mktags xref: $(EBIN_DIR)/yaws_generated.beam $(EBIN_DIR)/yaws_debug.beam $(AM_V_GEN)erl -noshell -pa $(EBIN_DIR) -s yaws_debug xref $(EBIN_DIR) clean-local: $(AM_V_at)rm -f $(EBIN_DIR)/yaws.app $(EBIN_DIR)/yaws.appup $(EBIN_FILES) $(AM_V_at)rm -f yaws_generated.erl mime_types.erl yaws_generated.erl: @srcdir@/yaws_generated.template @top_srcdir@/vsn.mk \ $(EBIN_DIR)/yaws.beam $(AM_V_at)(cd @srcdir@ && \ YAWS_VSN='@YAWS_VSN@' \ VARDIR='@localstatedir@' \ ETCDIR='@sysconfdir@' \ @abs_top_srcdir@/scripts/gen-yaws-generated) > yaws_generated.erl mime_types.erl: @top_builddir@/priv/mime.types $(EBIN_DIR)/mime_type_c.beam \ $(EBIN_DIR)/yaws.beam $(AM_V_GEN)$(ERL) -noshell -pa $(EBIN_DIR) -s mime_type_c generate $(EBIN_DIR)/yaws.app: @srcdir@/yaws.app.src $(AM_V_GEN)$(AWK) -v src="$(MODULES)" \ "/{vsn, *{cmd,/ { \ line = \$$0; \ sub(/{vsn.*/, \"{vsn, \\\"@YAWS_VSN@\\\"},\", line); \ print line; \ next; \ } \ /{modules,/ { \ line = \$$0; \ indent = index(line, \"[\"); \ line = substr(line, 1, indent); \ print line; \ split(src, mods); \ mods_count = 0; \ for (mod in mods) { \ mods_count++; \ } \ prefix = sprintf(\"%*s\", indent, \" \"); \ for (i = 1; i <= mods_count; i++) { \ mod = mods[i]; \ sub(/\.erl/, \"\", mod); \ if (i != mods_count) \ print prefix mod \",\"; \ else \ print prefix mod; \ } \ print prefix \"]},\"; \ next; \ } \ /\@APPDEPS\@/ { \ line = \$$0; \ sub(/\@APPDEPS\@/, \"$(APPDEPS)\", line); \ print line; \ next; \ } \ { print; }" $< > $@ $(EBIN_DIR)/yaws.appup: @srcdir@/yaws.appup.src $(AM_V_GEN)sed -e "s/%VSN%/@YAWS_VSN@/g" < $< > $@ $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: yaws-2.0.2/src/yaws_jsonrpc.erl0000664000175000017500000002172512605311412013437 00000000000000%% -*- coding: Latin-1 -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED %%% WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED %%% %%% Use module yaws_rpc.erl instead %%% %%% This module is deprecated. %%% %%% Do not report problems with this module, as they will not be fixed. You %%% should instead convert your code to use the yaws_rpc module. %%% %%% WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED %%% WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Copyright (C) 2003 Joakim Grebenö . %% All rights reserved. %% %% Copyright (C) 2006 Gaspar Chilingarov %% Gurgen Tumanyan %% All rights reserved. %% %% %% Redistribution and use in source and binary forms, with or without %% modification, are permitted provided that the following conditions %% are met: %% %% 1. Redistributions of source code must retain the above copyright %% notice, this list of conditions and the following disclaimer. %% 2. Redistributions in binary form must reproduce the above %% copyright notice, this list of conditions and the following %% disclaimer in the documentation and/or other materials provided %% with the distribution. %% %% THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS %% OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED %% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE %% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY %% DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL %% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE %% GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS %% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, %% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING %% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS %% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -module(yaws_jsonrpc). -author("Gaspar Chilingarov , Gurgen Tumanyan "). -export([handler/2]). -export([handler_session/2, handler_session/3]). %%-define(debug, 1). -include("yaws_debug.hrl"). -include("../include/yaws_api.hrl"). %%% ###################################################################### %%% public interface %%% %%% %%% use jsonrpc handler which can automagically start sessions if we need %%% handler_session(Args, Handler) -> handler_session(Args, Handler, 'SID'). %%% %%% allow overriding session Cookie name %%% handler_session(Args, Handler, SID_NAME) when is_atom(SID_NAME) -> handler_session(Args, Handler, atom_to_list(SID_NAME)); handler_session(Args, Handler, SID_NAME) -> handler(Args, Handler, {session, SID_NAME}). % go to generic handler %%% %%% xmlrpc:handler compatible call %%% no session support will be available handler(Args, Handler) -> handler(Args, Handler, simple). %%% ###################################################################### %%% private functions %%% %%% we should be called from yaws page or module handler(Args, Handler, Type) when is_record(Args, arg) -> case parse_request(Args) of ok -> handle_payload(Args, Handler, Type); {status, StatusCode} -> % cannot parse request send(Args, StatusCode) end. -define(ERROR_LOG(Reason), error_logger:error_report({?MODULE, ?LINE, Reason})). %%% %%% check that request come in reasonable protocol version and reasonable method %%% parse_request(Args) -> case {(Args#arg.req)#http_request.method, (Args#arg.req)#http_request.version} of {'POST', {1,0}} -> ?Debug("HTTP Version 1.0~n", []), ok; {'POST', {1,1}} -> ?Debug("HTTP Version 1.1~n", []), ok; {'POST', _HTTPVersion} -> {status, 505}; {_Method, {1,1}} -> {status, 501}; _ -> {status, 400} end. handle_payload(Args, Handler, Type) -> Payload = binary_to_list(Args#arg.clidata), ?Debug("jsonrpc plaintext call ~p ~n", [Payload]), case decode_handler_payload(Payload) of {ok, DecodedPayload, ID} -> ?Debug("json2erl decoded call ~p ~n", [DecodedPayload]), eval_payload(Args, Handler, DecodedPayload, Type, ID); {error, Reason} -> ?ERROR_LOG({html, json2erl, Payload, Reason}), send(Args, 400) end. %%% %%% call handler/3 and provide session support eval_payload(Args, {M, F}, Payload, {session, CookieName},ID) -> {SessionValue, Cookie} = case yaws_api:find_cookie_val(CookieName, (Args#arg.headers)#headers.cookie) of [] -> % have no session started, just call handler {undefined, undefined}; Cookie2 -> % get old session data case yaws_api:cookieval_to_opaque(Cookie2) of {ok, OP} -> yaws_api:cookieval_to_opaque(Cookie2), {OP, Cookie2}; {error, _ErrMsg} -> % cannot get corresponding session {undefined, undefined} end end, case catch M:F(Args#arg.state, Payload, SessionValue) of {'EXIT', Reason} -> ?ERROR_LOG({M, F, {'EXIT', Reason}}), send(Args, 500); {error, Reason} -> ?ERROR_LOG({M, F, Reason}), send(Args, 500); {false, ResponsePayload} -> %% do not have updates in session data encode_send(Args, 200, ResponsePayload, [], ID); {true, _NewTimeout, NewSessionValue, ResponsePayload} -> %% be compatible with xmlrpc module CO = case NewSessionValue of undefined when Cookie == undefined -> []; % nothing to do undefined -> % rpc handler requested session delete yaws_api:delete_cookie_session(Cookie), []; %% XXX: may be return set-cookie with empty val? _ -> %% any other value will stored in session case SessionValue of undefined -> %% got session data and should start %% new session now Cookie1 = yaws_api:new_cookie_session( NewSessionValue), yaws_api:setcookie(CookieName, Cookie1, "/"); _ -> yaws_api:replace_cookie_session( Cookie, NewSessionValue), [] % nothing to add to yaws data end end, encode_send(Args, 200, ResponsePayload, CO, ID) end; %%% %%% call handler/2 without session support %%% eval_payload(Args, {M, F}, Payload, simple, ID) -> case catch M:F(Args#arg.state, Payload) of {'EXIT', Reason} -> ?ERROR_LOG({M, F, {'EXIT', Reason}}), send(Args, 500); {error, Reason} -> ?ERROR_LOG({M, F, Reason}), send(Args, 500); {false, ResponsePayload} -> encode_send(Args, 200, ResponsePayload, [],ID); {true, _NewTimeout, _NewState, ResponsePayload} -> encode_send(Args, 200, ResponsePayload, [],ID) end. %%% XXX compatibility with XMLRPC handlers %%% XXX - potential bug here? encode_send(Args, StatusCode, [Payload], AddOn, ID) -> encode_send(Args, StatusCode, Payload, AddOn, ID); encode_send(Args, StatusCode, Payload, AddOn, ID) -> {ok, EncodedPayload} = encode_handler_payload(Payload, ID), send(Args, StatusCode, EncodedPayload, AddOn). send(Args, StatusCode) -> send(Args, StatusCode, "", []). send(Args, StatusCode, Payload, AddOnData) when not is_list(AddOnData) -> send(Args, StatusCode, Payload, [AddOnData]); send(_Args, StatusCode, Payload, AddOnData) -> A = [ {status, StatusCode}, {content, "text/xml", Payload}, {header, {content_length, lists:flatlength(Payload) }} ] ++ AddOnData, A. encode_handler_payload({response, [ErlStruct]},ID) -> encode_handler_payload({response, ErlStruct}, ID); encode_handler_payload({response, ErlStruct},ID) -> StructStr = json2:encode({struct, [{result, ErlStruct}, {id, ID}]}), {ok, StructStr}. decode_handler_payload(JSonStr) -> try {ok, JSON} = json2:decode_string(JSonStr), Method = list_to_atom(jsonrpc:s(JSON, method)), {array, Args} = jsonrpc:s(JSON, params), ID = jsonrpc:s(JSON, id), {ok, {call, Method, Args}, ID} catch error:Err -> {error, Err} end. yaws-2.0.2/src/yaws_logger.erl0000664000175000017500000000677212605311412013245 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_logger.erl %%% Author : Christopher Faulet %%% Purpose : %%% Created : 14 Dec 2010 by Christopher Faulet %%%---------------------------------------------------------------------- -module(yaws_logger). -author('christopher@yakaz.com'). -include_lib("kernel/include/file.hrl"). -export([behaviour_info/1]). %% API -export([ open_log/3, close_log/2, close_logs/0, rotate/1, accesslog/6, authlog/4 ]). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). -record(log, {id, amod, data}). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- behaviour_info(callbacks) -> [{open_log,3}, {close_log,3}, {wrap_log,4}, {write_log,4}]; behaviour_info(_Other) -> undefined. open_log(SConf, auth, Dir) when ?sc_has_auth_log(SConf) -> do_open_log(SConf, auth, Dir); open_log(SConf, access, Dir) when ?sc_has_access_log(SConf) -> do_open_log(SConf, access, Dir); open_log(_, _, _) -> false. close_log(SConf, Type) -> case ets:lookup(yaws_log, {Type, SConf#sconf.servername}) of [AL] -> do_close_log(AL), ets:delete(yaws_log, {Type, SConf#sconf.servername}), ok; [] -> ok end. close_logs() -> do_close_logs(ets:first(yaws_log)), ets:delete_all_objects(yaws_log), ok. rotate(LogWrapSize) -> do_rotate(ets:first(yaws_log), LogWrapSize). accesslog(#sconf{servername=Srv}, Ip, Req, InH, OutH, Time) -> case ets:lookup(yaws_log, {access, Srv}) of [#log{amod=Mod, data=Data}] -> catch Mod:write_log(Srv, access, Data, {Ip, Req, InH, OutH, Time}); _ -> ok end. authlog(#sconf{servername=Srv}, IP, Path, Item) -> case ets:lookup(yaws_log, {auth, Srv}) of [#log{amod=Mod, data=Data}] -> catch Mod:write_log(Srv, auth, Data, {IP, Path, Item}); _ -> ok end. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- do_open_log(#sconf{servername=Srv, logger_mod=Mod}, Type, Dir) -> Id = {Type, Srv}, case ets:lookup(yaws_log, Id) of [] -> case catch Mod:open_log(Srv, Type, Dir) of {true, Data} -> AL = #log{id={Type, Srv}, amod=Mod, data=Data}, ets:insert(yaws_log, AL), true; _ -> false end; _ -> %% Already exists. Might be the case that both http and https %% has been enabled and we don't want to open the same log twice. true end. do_close_log(#log{id={Type, Srv}, amod=Mod, data=Data}) -> catch Mod:close_log(Srv, Type, Data). do_close_logs('$end_of_table') -> ok; do_close_logs(Id) -> [AL] = ets:lookup(yaws_log, Id), do_close_log(AL), do_close_logs(ets:next(yaws_log, Id)). do_rotate('$end_of_table', _) -> ok; do_rotate(Id, LogWrapSize) -> [#log{id={Type, Srv}, amod=Mod, data=Data}=AL] = ets:lookup(yaws_log, Id), Data1 = Mod:wrap_log(Srv, Type, Data, LogWrapSize), ets:insert(yaws_log, AL#log{data=Data1}), do_rotate(ets:next(yaws_log, Id), LogWrapSize). yaws-2.0.2/src/yaws_compile.erl0000664000175000017500000004237712605311412013417 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_compile.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 20 Feb 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws_compile). -author('klacke@hyber.org'). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). %% tada !! %% returns a CodeSpec which is: %% a list {data, NumChars} | %% {mod, LineNo, YawsFile, NumSkipChars, Mod, Func} | %% {error, NumSkipChars, E}} %% each erlang fragment inside .... is compiled into %% its own module -record(comp, { gc, %% global conf sc, %% server conf startline = 0, modnum = 1, infile, infd, outfile, outfd}). -export([compile_file/1]). %% internal exports -export([compiler_proc/3]). comp_opts(GC) -> ?Debug("I=~p~n", [GC#gconf.include_dir]), I = lists:map(fun(Dir) -> {i, Dir} end, GC#gconf.include_dir), Warnings = case get(use_yfile_name) of true -> [return_warnings, debug_info]; _ -> [] end, Opts = [binary, return_errors] ++ Warnings ++ I, ?Debug("Compile opts = ~p~n", [Opts]), Opts. compile_file(File) -> GC=get(gc), SC=get(sc), case get(use_yfile_name) of true -> %% Run by 'yaws -check' put(yfile,filename:rootname(yaws:to_list(File))); _ -> put(yfile,yaws:to_list(File)) end, %% broken erlang compiler isn't %% reentrant, can only have one erlang compiler at a time running global:trans({yaws, self()}, fun() -> ?Debug("Compile ~s~n", [File]), case file_open(File) of {ok, Fd} -> Spec = compile_file( #comp{infile = File, infd = Fd, gc = GC, sc = SC}, 1, get_line(), init, 0, [], 0), erase(yfile), erase(yfile_data), erase(yfile_data_orig), ?Debug("Spec: ~p~n", [Spec]), Spec; _Err -> yaws:elog("can't open ~s~n", [File]), exit(normal) end end, [node()], infinity). clump_data([{data, I}, {data, J} | Tail]) -> clump_data([{data, I+J}|Tail]); clump_data([H|T]) -> [H|clump_data(T)]; clump_data([]) -> []. compile_file(C, _LineNo, eof, _Mode, NumChars, Ack, Errors) -> file_close(C#comp.infd), {ok, [{errors, Errors} | clump_data(lists:reverse([{data, NumChars} |Ack]))]}; %% skip initial space if first thing is otherwise not compile_file(C, LineNo, Chars, init, NumChars, Ack, Errs) -> case Chars -- [$\s, $\t, $\n, $\r] of [] -> ?Debug("SKIP ~p~n", [Chars]), L=length(Chars), compile_file(C, LineNo+1, line(), init, NumChars-L, Ack, Errs); " %% first chunk is erl, skip whistespace compile_file(C, LineNo, Chars, html, NumChars, Ack, Errs); _ -> %% first chunk is html, keep whitespace file_position_bof(), compile_file(C,1,line(),html,0,[], Errs) end; compile_file(C, LineNo, Chars = " ?Debug("start erl:~p",[LineNo]), C2 = new_out_file(LineNo, C, Tail, C#comp.gc), C3 = C2#comp{startline = LineNo}, L = length(Chars), if NumChars > 0 -> compile_file(C3, LineNo+1, line() , erl,L, [{data, NumChars} | Ack], Es); true -> %% just ignore zero byte data segments compile_file(C3, LineNo+1, line() , erl, L + (-NumChars), Ack, Es) %hack end; compile_file(C, LineNo, Chars = "" ++ _Tail, html, NumChars, Ack,Es) -> ?Debug("start verbatim:~p",[LineNo]), Len = length(Chars), C2 = C#comp{outfile = ["
\n"]},  %% use as accumulator
    compile_file(C2,  LineNo+1, line() , verbatim , Len,
                 [{data, NumChars} | Ack], Es);

compile_file(C, LineNo,  Chars = "" ++ _Tail, verbatim,
             NumChars, Ack, Es) ->
    Data = list_to_binary(lists:reverse(["
\n" | C#comp.outfile])), Len = length(Chars), compile_file(C#comp{outfile = undefined}, LineNo, line(), html, 0, [{verbatim, NumChars+Len, Data} |Ack], Es); compile_file(C, LineNo, Chars, verbatim, NumChars, Ack,Es) -> case has_str(Chars, ["
"]) of {ok, Skipped, Chars2} -> compile_file(C, LineNo, Chars2, verbatim, NumChars + Skipped, Ack,Es); false -> C2 = C#comp{outfile = [yaws_api:htmlize(Chars) | C#comp.outfile]}, compile_file(C2, LineNo+1, line(), verbatim, NumChars + length(Chars), Ack,Es) end; compile_file(C, LineNo, _Chars = "
" ++ Tail, erl, NumChars, Ack, Es) -> ?Debug("stop erl:~p",[LineNo]), file:close(C#comp.outfd), case proc_compile_file(C#comp.outfile, comp_opts(C#comp.gc)) of {ok, ModuleName, Binary, Warnings} -> case get(use_yfile_name) of true -> file:write_file("../../ebin/" ++ filename:rootname( C#comp.outfile)++".beam", Binary); _ -> ok end, comp_warn(C, Warnings), case code:load_binary(ModuleName, C#comp.outfile, Binary) of {module, ModuleName} -> C2 = C#comp{modnum = C#comp.modnum+1}, L2 = check_exported(C, LineNo, NumChars, ModuleName), compile_file(C2, LineNo, Tail, html, 0, L2++[{skip, 6}|Ack], Es); Err -> A2 = gen_err(C, LineNo, NumChars, ?F("Cannot load module ~p: ~p", [ModuleName, Err])), compile_file(C, LineNo, Tail, html, 0, [A2, {skip, 6}|Ack], Es+1) end; {error, Errors, Warnings} -> %% FIXME remove outfile here ... keep while debuging A2 = comp_err(C, LineNo, NumChars, Errors, Warnings), compile_file(C, LineNo, Tail, html, 0, [A2, {skip, 6}|Ack], Es+1); {error, Str} -> %% this is boring but does actually happen %% in order to get proper user errors here we need to catch i/o %% or hack compiler/parser yaws:elog("Dynamic compile error in file ~s (~s), line ~w~n~s", [C#comp.infile, C#comp.outfile,LineNo, Str]), A2 = {error, NumChars, ?F("
 Dynamic compile error in file "
                                      " ~s line ~w~n~s 
", [C#comp.infile, LineNo, Str])}, compile_file(C, LineNo, Tail, html, 0, [A2, {skip, 6}|Ack], Es+1) end; compile_file(C, LineNo, Chars, erl, NumChars, Ack,Es) -> case has_str(Chars, [""]) of {ok, Skipped, Chars2} -> compile_file(C, LineNo, Chars2, erl, NumChars + Skipped, Ack,Es); false -> ?Debug("Gen: ~s", [Chars]), io:format(C#comp.outfd, "~s", [Chars]), compile_file(C, LineNo+1, line(), erl, NumChars + length(Chars), Ack,Es) end; compile_file(C, LineNo, [], html, NumChars, Ack, Es) -> compile_file(C, LineNo+1, line(), html, NumChars, Ack, Es); compile_file(C, LineNo, Chars, html, NumChars, Ack,Es) -> case has_str(Chars, [""]) of {ok, Skipped, " compile_file(C, LineNo, Chars2, html, NumChars+Skipped, Ack, Es); {ok, Skipped, ""++_ = Chars2} -> compile_file(C, LineNo, Chars2, html, NumChars+Skipped, Ack, Es); {ok, Skipped, "%%"++Chars2} -> compile_file(C, LineNo, Chars2, binding, 2, [{data, NumChars+Skipped}|Ack], Es); false -> compile_file(C, LineNo, tl(Chars), html, NumChars+1, Ack, Es) end; compile_file(C, LineNo, [], binding, NumChars, Ack, Es) -> compile_file(C, LineNo+1, line(), html, NumChars, Ack, Es); compile_file(C, LineNo, "%%"++Chars, binding, NumChars, Ack, Es) -> compile_file(C, LineNo, Chars, html, 0, [{binding, NumChars+2}|Ack], Es); compile_file(C, LineNo, [_H|T], binding, NumChars, Ack, Es) -> compile_file(C, LineNo, T, binding, NumChars+1, Ack, Es). has_str(L, Strs) -> has_str(L, Strs, 0). has_str([H|T], Strs, Num) -> case yaws:is_space(H) of true -> has_str(T, Strs, Num+1); false -> case lists:any(fun(Str) -> lists:prefix(Str, [H|T]) end, Strs) of true -> {ok, Num, [H|T]}; false -> false end end; has_str(_,_,_) -> false. check_exported(C, LineNo, NumChars, Mod) -> case is_exported(out, 1, Mod) of true -> [{mod, C#comp.startline, C#comp.infile, NumChars,Mod,out}]; false -> ?Debug("XX ~p~n", [C]), [gen_err(C, LineNo, NumChars, "out/1 is not defined ")] end. line() -> get_line(). is_exported(Fun, A, Mod) -> case (catch Mod:module_info()) of List when is_list(List) -> case lists:keysearch(exports, 1, List) of {value, {exports, Exp}} -> lists:member({Fun, A}, Exp); _ -> false end; _ -> false end. new_out_file_module(Tail) -> case Tail of ">" ++ _ -> Mnum = case catch gen_server:call(yaws_server, mnum, infinity) of {'EXIT', _} -> 1; Other -> Other end, Prefix = case get(use_yfile_name) of true -> filename:rootname(get(yfile))++"_yaws"; _ -> "m" end, Prefix ++ integer_to_list(Mnum); _ -> case string:tokens(Tail, " =>\r\n\"") of ["module", Module] -> Module end end. new_out_file_name(Module, GC) -> case get(use_yfile_name) of true -> Module ++ ".erl"; _ -> filename:join([yaws:id_dir(GC#gconf.id), Module ++ ".erl"]) end. %% this will generate 10 lines new_out_file(Line, C, Tail, GC) -> Module = new_out_file_module(Tail), OutFile = new_out_file_name(Module, GC), ?Debug("Writing outout file~s~n", [OutFile]), {ok, Out} = file:open(OutFile, [write]), ok = io:format(Out, "-module(\'~s\').~n-export([out/1]).~n~n", [Module]), ok = io:format(Out, "-yawsfile(\'~s\').~n",[get(yfile)]), io:format(Out, "%%~n%% code at line ~w from file ~s~n%%~n", [Line, C#comp.infile]), io:format(Out, "-import(yaws_api, [f/2, fl/1, postvar/2, queryvar/2])." " ~n~n", []), io:format(Out, '-include("~s/include/yaws_api.hrl").~n', [GC#gconf.yaws_dir]), C#comp{outfd = Out, outfile = OutFile}. gen_err(C, _LineNo, NumChars, Err) -> S = io_lib:format("

Error in File ~s Erlang code beginning " "at line ~w~n" "Error is: ~p~n", [C#comp.infile, C#comp.startline, Err]), yaws:elog("~s~n", [S]), {error, NumChars, S}. comp_err(C, LineNo, NumChars, Err, Warns) -> case get(use_yfile_name) of true -> report_errors(C, Err), report_warnings(C, Warns), {error, NumChars, ""}; _ -> comp_err(C, LineNo, NumChars, Err) end. comp_err(C, _LineNo, NumChars, Err) -> case Err of [{_FileName, [ {Line0, Mod, E} |_]} |_] when is_integer(Line0) -> Line = Line0 + C#comp.startline - 10, ?Debug("XX ~p~n", [{_LineNo, Line0}]), Str = io_lib:format("~s:~w:~n ~s\ngenerated file at: ~s~n", [C#comp.infile, Line, apply(Mod, format_error, [E]), C#comp.outfile ]), HtmlStr = ?F("~n

~nDynamic compile error: ~s~n
~n", [Str]), yaws:elog("Dynamic compiler err ~s", [Str]), {error, NumChars, HtmlStr}; _Other -> yaws:elog("Dynamic compile error ~p", [Err]), {error, NumChars, ?F("
 Compile error - "
                                 "Other err ~p
~n", [Err])} end. comp_warn(C, Warnings) -> case get(use_yfile_name) of true -> report_warnings(C, Warnings); _ -> ok end. %% due to compiler not producing proper error %% we NEED to catch all io produced by the compiler proc_compile_file(F, Opts) -> G = group_leader(), group_leader(self(), self()), P = proc_lib:spawn(?MODULE, compiler_proc, [self(), F, Opts]), Res = get_compiler_data(P, []), group_leader(G, self()), Res. compiler_proc(Top, F, Opts) -> R = (catch compile:file(F, Opts)), Top ! {self(), result, R}. get_compiler_data(P, Ack) -> receive {P, result, {ok, Mod, Bin}} -> {ok, Mod, Bin, []}; {P, result, {ok, Mod, Bin, Warnings}} -> {ok, Mod, Bin, Warnings}; {io_request, P1, P2, {put_chars, M, F, A}} -> P1 ! {io_reply, P2, ok}, Str = apply(M, F, A), get_compiler_data(P, [Str|Ack]); {P, result, {error, Errors, Warnings}} -> {error, Errors, Warnings}; {P, result, error} -> S = lists:map( fun(S) -> S ++ "\n" end, lists:reverse(Ack)), {error, S}; {P, result, {'EXIT', Reason}} -> S = lists:flatten(io_lib:format("~p", [Reason])), {error, S} end. %% This code is so that we get the \r in the line %% when we're parsing msdos files. file_open(Fname) -> case file:read_file(Fname) of {ok, Bin} -> put(yfile_data, binary_to_list(Bin)), put(yfile_data_orig, Bin), {ok, yfile_data}; Err -> Err end. file_close(Key) -> erase(Key). file_position_bof() -> put(yfile_data, binary_to_list(get(yfile_data_orig))). get_line() -> case get (yfile_data) of [] -> eof; Chars -> case get_line_from_chars(Chars, []) of {ok, Line, Tail} -> put (yfile_data, Tail), Line; need_more -> put(yfile_data, []), Chars end end. get_line_from_chars([$\r, $\n | Tail], Line) -> {ok, lists:reverse([$\n, $\r|Line]), Tail}; get_line_from_chars([$\n | Tail], Line) -> {ok, lists:reverse([$\n|Line]), Tail}; get_line_from_chars([], _Line) -> need_more; get_line_from_chars([H|T], Line) -> get_line_from_chars(T, [H|Line]). %% ----------------------------------------------------------------- %% From compile.erl in order to print proper error/warning messages %% if compiled with check option. report_errors(C, Errors) -> File = "./" ++ filename:basename(C#comp.infile), SLine = C#comp.startline - 10, lists:foreach(fun ({{_F,_L},Eds}) -> list_errors(File, SLine, Eds); ({_F,Eds}) -> list_errors(File, SLine, Eds) end, Errors). report_warnings(C, Ws0) -> File = "./" ++ filename:basename(C#comp.infile), SLine = C#comp.startline - 10, Ws1 = lists:flatmap(fun({{_F,_L},Eds}) -> format_message(File, SLine, Eds); ({_F,Eds}) -> format_message(File, SLine, Eds) end, Ws0), Ws = ordsets:from_list(Ws1), lists:foreach(fun({_,Str}) -> io:put_chars(Str) end, Ws). format_message(F, SLine, [{Line0,Mod,E}|Es]) -> Line = Line0 + SLine, M = {{F,Line},io_lib:format("~s:~w: Warning: ~s\n", [F,Line,Mod:format_error(E)])}, [M|format_message(F, SLine, Es)]; format_message(F, SLine, [{Mod,E}|Es]) -> M = {none,io_lib:format("~s: Warning: ~s\n", [F,Mod:format_error(E)])}, [M|format_message(F, SLine, Es)]; format_message(_, _, []) -> []. %% list_errors(File, StartLine, ErrorDescriptors) -> ok list_errors(F, SLine, [{Line0,Mod,E}|Es]) -> Line = Line0 + SLine, io:fwrite("~s:~w: ~s\n", [F,Line,Mod:format_error(E)]), list_errors(F, SLine, Es); list_errors(F, SLine, [{Mod,E}|Es]) -> io:fwrite("~s: ~s\n", [F,Mod:format_error(E)]), list_errors(F, SLine, Es); list_errors(_F, _SLine, []) -> ok. yaws-2.0.2/src/yaws_ctl.erl0000664000175000017500000004405512605311412012544 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_ctl.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 29 Apr 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- %% some code to remoteley control a running yaws server -module(yaws_ctl). -author('klacke@bluetail.com'). -include_lib("kernel/include/file.hrl"). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). -export([start/2, actl_trace/1]). -export([ls/1,hup/1,stop/1,status/1,load/1, check/1,trace/1, debug_dump/1, stats/1, running_config/1, configtest/1]). %% internal -export([run/1, aloop/3, handle_a/3]). %% assumes the appropriate file structures %% are already created with the right perms start(_GC, FirstTime) when FirstTime == false -> ok; start(GC, true) -> proc_lib:start_link(?MODULE, run, [GC]). run(GC) -> %% First check if there is already a Yaws system running %% with the same sid. case connect(GC#gconf.id) of {ok, Sock, _Key} -> %% Not good, gen_tcp:close(Sock), e("There is already a yaws system running with the same ~n" " id <~p> on this computer and this user, ~n" " set another id in the yaws conf file ~n", [GC#gconf.id]); {error, eacces} -> %% We're not allowed to open the ctl file e("Error reading ~s, you don't have access rights to read it", [yaws:ctl_file(GC#gconf.id)]); {error, _} -> %% Fine, this should be the case run_listen(GC) end. rand() -> case os:type() of {win32, _} -> {A1, A2, A3}=yaws:get_time_tuple(), random:seed(A1, A2, A3), random:uniform(1 bsl 64); _ -> try crypto:start(), crypto:rand_uniform(0, 1 bsl 64) catch _:_ -> error_logger:warning_msg("Running without crypto app\n"), {A1, A2, A3}=yaws:get_time_tuple(), random:seed(A1, A2, A3), random:uniform(1 bsl 64) end end. ctl_args() -> [{packet, 2}, {active, false}, binary, {ip, {127,0,0,1}}, {reuseaddr, true}]. run_listen(GC) -> case gen_tcp:listen(0, ctl_args()) of {ok, L} -> case inet:sockname(L) of {ok, {_, Port}} -> Key = rand(), case w_ctl_file(GC#gconf.id, Port, Key) of ok -> proc_lib:init_ack(ok), aloop(L, GC, Key); error -> e( "Failed to create/manipulate the ctlfile ~n" "called ~s~n" "Either problems with permissions or " " earlier runs of yaws ~nwith the same id " " <~p> as this, check dir for perms~n", [yaws:ctl_file(GC#gconf.id), GC#gconf.id]) end; Err -> e("Cannot get sockname for ctlsock: ~p",[Err] ) end; Err -> e("Cannot listen on ctl socket, fatal: ~p", [Err]) end. e(Fmt, Args) -> proc_lib:init_ack({error, io_lib:format(Fmt, Args)}), exit(normal). %% write the control file, set perms of the file %% so that only this user can read the file %% That way we're making sure different users %% cannot manipulate each others webservers w_ctl_file(Sid, Port, Key) -> case catch begin F = yaws:ctl_file(Sid), error_logger:info_msg("Ctlfile : ~s~n", [F]), file:write_file(F, io_lib:format("~w.", [{Port,Key}])), {ok, FI} = file:read_file_info(F), ok = file:write_file_info(F, FI#file_info{mode = 8#00600}) end of {'EXIT', _} -> error; _ -> ok end. aloop(L, GC, Key) -> case gen_tcp:accept(L) of {ok, A} -> proc_lib:spawn (?MODULE, handle_a, [A, GC, Key]); Err -> error_logger:format("yaws_ctl failed to accept: ~p~n", [Err]), timer:sleep(2000), ignore end, ?MODULE:aloop(L, GC, Key). handle_a(A, GC, Key) -> case gen_tcp:recv(A, 0) of {ok, Data} -> case catch binary_to_term(Data) of {hup, Key} -> Res = yaws:dohup(A), Res; {stop, Key} -> error_logger:info_msg("Stopping yaws\n",[]), gen_tcp:send(A, io_lib:format( "stopping yaws with id=~p\n", [GC#gconf.id])), file:delete(yaws:ctl_file(GC#gconf.id)), init:stop(); {{trace, What}, Key} -> Res = actl_trace(What), gen_tcp:send(A, Res), gen_tcp:close(A); {status, Key} -> a_status(A), gen_tcp:close(A); {{load, Mods}, Key} -> a_load(A, Mods), gen_tcp:close(A); {id, Key} -> a_id(A), gen_tcp:close(A); {debug_dump, Key} -> a_debug_dump(A), gen_tcp:close(A); {stats, Key} -> a_stats(A), gen_tcp:close(A); {running_config, Key} -> a_running_config(A), gen_tcp:close(A); {Other, Key} -> gen_tcp:send(A, io_lib:format("Other: ~p~n", [Other])), gen_tcp:close(A); _Other -> gen_tcp:close(A) end; {error, _} -> gen_tcp:close(A) end. %% We implement this by reloading a patched config actl_trace(What) -> case lists:member(What, [traffic, http, off]) of true -> {ok, GC, SCs} = yaws_api:getconf(), case GC#gconf.trace of false when What /= off-> yaws_api:setconf(GC#gconf{trace = {true, What}},SCs), io_lib:format( "Turning on trace of ~p to file ~s~n", [What, filename:join([GC#gconf.logdir, "trace." ++ atom_to_list(What)])]); false when What == off -> io_lib:format("Tracing is already turned off ~n",[]); {true, _} when What == off -> yaws_api:setconf(GC#gconf{trace = false},SCs), "Turning trace off \n"; {true, What} -> io_lib:format("Trace of ~p is already turned on, ose 'off' " "to turn off~n", [What]); {true, _Other} -> yaws_api:setconf(GC#gconf{trace = {true, What}},SCs), io_lib:format( "Turning on trace of ~p to file ~s~n", [What, filename:join([GC#gconf.logdir, "trace." ++ atom_to_list(What)])]) end; false -> "Need either http | traffic | off as argument\n" end. f(Fmt, As) -> io_lib:format(Fmt, As). a_id(Sock) -> ID = gen_server:call(yaws_server, id, infinity), gen_tcp:send(Sock, ID), ok. a_status(Sock) -> gen_tcp:send(Sock, a_status()). a_status() -> try {UpTime, L} = yaws_server:stats(), {Days, {Hours, Minutes, _Secs}} = UpTime, UpStr = f("~n Uptime: ~w Days, ~w Hours, ~w Minutes ~n", [Days, Hours, Minutes]), Header = f("IP Port Connections Sessions Requests~n", []), Lines = lists:map(fun({IP0, Port, Conns, Sess, Reqs}) -> IP = format_ip(IP0), f("~s ~p ~p ~p ~p~n", [IP, Port, Conns, Sess, Reqs]) end, L), [Header, Lines, UpStr] catch _:Err -> io_lib:format("Cannot get status ~p~n", [Err]) end. a_debug_dump(Sock) -> gen_tcp:send(Sock, a_status()), yaws_debug:do_debug_dump(Sock). vsn(IP) when size(IP) =:= 4 -> "(ipv4)"; vsn(IP) when size(IP) =:= 8 -> "(ipv6)". -define(IPV4_FMT, "~p.~p.~p.~p"). -define(IPV6_FMT, "~2.16.0b~2.16.0b:~2.16.0b~2.16.0b:~2.16.0b~2.16.0b:~2.16.0b~2.16.0b"). format_ip(IP) -> case size(IP) of 4 -> {A, B, C, D} = IP, io_lib:format(?IPV4_FMT, [A, B, C, D]); 8 -> {A, B, C, D, E, F, G, H} = IP, io_lib:format(?IPV6_FMT, [A, B, C, D, E, F, G, H]) end. a_running_config(Sock) -> gen_tcp:send(Sock, a_running_config()). a_running_config() -> {ok, GC, Groups} = yaws_server:getconf(), GcStr = ?format_record(GC, gconf), L = lists:map(fun(Group) -> ["** GROUP ** \n", lists:map( fun(SC) -> ?format_record(SC, sconf) end, Group) ] end, Groups), ["** GLOBAL CONF ** \n", GcStr, L]. a_stats(Sock) -> gen_tcp:send(Sock, a_stats()). a_stats() -> {ok, _GC, Servers0} = yaws_server:getconf(), Servers1 = lists:flatten(Servers0), %% io:format("~p~n", [Servers1]), Servers2 = parse(Servers1), case Servers2 of [] -> f("No statistics available~n", []); Servers2 -> Stats = fstats(Servers2), Header = f("Host IP Port Hits Sent~n", []), Lines = lists:map(fun({Host, IP0, Port, {Hits, Sent}}) -> %% we don't use inet_parse:ntoa/1 %% since it's not documented IP = format_ip(IP0), IPVsn = vsn(IP0), f("~s~s ~s ~p ~p ~p~n", [Host, IPVsn, IP, Port, Hits, Sent]) end, Stats), [Header, Lines] end. parse(V) -> parse(V, []). parse([], Acc) -> Acc; parse([#sconf{stats=undefined}|Tail], Acc) -> parse(Tail, Acc); parse([#sconf{listen=IP, port=Port, servername=Servername, stats=Stats}|Tail], Acc) -> Host = {Servername, IP, Port, Stats}, parse(Tail, [Host|Acc]). fstats(S) -> fstats(S, []). fstats([], Acc) -> lists:keysort(1, Acc); fstats([{IP, Port, Server, Stats}|Tail], Acc) -> S = {IP, Port, Server, yaws_stats:get(Stats)}, fstats(Tail, [S|Acc]). a_load(A, Mods) -> case purge(Mods) of ok -> gen_tcp:send(A, f("~p~n", [loadm(Mods)])); Err -> gen_tcp:send(A, f("~p~n", [Err])) end. loadm([]) -> []; loadm([M|Ms]) -> [code:load_file(M)|loadm(Ms)]. purge(Ms) -> case purge(Ms, []) of [] -> ok; L -> {cannot_purge, L} end. purge([], Ack) -> Ack; purge([M|Ms], Ack) -> case code:soft_purge(M) of true -> purge(Ms, Ack); false -> purge(Ms, [M|Ack]) end. connect(Sid) -> connect_file(yaws:ctl_file(Sid)). %% The ctl file contains the port number the yaws server %% is listening at and secret key string. connect_file(CtlFile) -> case file:consult(CtlFile) of {ok, [{Port, Key}]} -> case gen_tcp:connect({127,0,0,1}, Port, [{active, false}, {reuseaddr, true}, binary, {packet, 2}], 2000) of {ok, Socket} -> case inet:port(Socket) of {ok,Port} -> {error, erefused}; _X -> {ok, Socket, Key} end; Err -> Err end; {ok, Terms} -> {error, {content, Terms}}; Err -> Err end. actl(SID, Term) -> case connect(SID) of {error, eacces} -> io:format("Another user is using the yaws sid <~p>, ~n" "You are not allowd to read the file <~s>, ~n" "specify by <-I id> which yaws system you want" " to control~n", [SID, yaws:ctl_file(SID)]), timer:sleep(10), erlang:halt(1); {error, econnrefused} -> io:format("No yaws system responds~n",[]), timer:sleep(10), erlang:halt(2); {error, {content,Terms}} -> io:format("The ctlfile ~s is readable but its content~n" "~p~n" "isn't in YAWS control file format~n", [yaws:ctl_file(SID),Terms]), timer:sleep(10), erlang:halt(2); {error, Reason} -> io:format("You failed to read the ctlfile ~s~n" "error was: <~p>~n" "specify by <-I id> which yaws system you want" " to control~n", [yaws:ctl_file(SID), Reason]), timer:sleep(10), erlang:halt(3); {ok, Socket, Key} -> gen_tcp:send(Socket, term_to_binary({Term, Key})), Ret = s_cmd(Socket, SID, 0), timer:sleep(40), %% sucks bigtime, we have no good way to flush io case Ret of ok when Term == stop -> %% wait for Yaws node to truly stop. case gen_tcp:recv(Socket, 0) of {error, closed} -> erlang:halt(0); Other -> io:format("Stopping yaws: ~p~n", [Other]), erlang:halt(3) end; ok -> erlang:halt(0); error -> erlang:halt(4) end end. s_cmd(Fd, SID, Count) -> case gen_tcp:recv(Fd, 0) of {ok, Bin} -> io:format("~s", [binary_to_list(Bin)]), s_cmd(Fd, SID, Count+1); {error, closed} when Count > 0 -> gen_tcp:close(Fd); Err -> io_lib:format("yaws server for yaws id <~p> not " "responding: ~p ~n", [SID, Err]), error end. %% List existing yaws nodes on this machine for this user ls(_) -> Dir = filename:join([yaws:tmpdir(), "yaws"]), case file:list_dir(Dir) of {ok, List} -> io:format("~-15s~-10s~-10s~n", ["Id", "Status", "Owner"]), io:format("-------------------------------------~n",[]), lists:foreach( fun(IdDir) -> lls(IdDir) end, List); _ -> ok end, init:stop(). lls(IdDir) -> CtlFile = yaws:ctl_file(IdDir), case {file:read_file_info(CtlFile), file:read_file(CtlFile)} of {{ok, FI}, {error, eacces}} -> User = yaws:uid_to_name(FI#file_info.uid), io:format("~-15s~-10s~-10s~n", [IdDir, "noaccess", User]); {{ok, FI}, {ok, _Bin}} -> Running = case connect(IdDir) of {ok, Sock, _Key} -> gen_tcp:close(Sock), "running"; {error, timeout} -> "hanging??"; {error, eacces} -> "noaccess"; _Err -> "stopped" end, User = yaws:uid_to_name(FI#file_info.uid), io:format("~-15s~-10s~-10s~n", [IdDir, Running, User]); _ -> ok end. %% send a hup (kindof) to the yaws server to make it %% reload its configuration and clear its caches hup([SID]) -> actl(SID, hup). %% stop a daemon stop([SID]) -> actl(SID, stop). %% query a daemon for status/stats status([SID]) -> actl(SID, status). load(X) -> [SID | Modules] = lists:reverse(X), actl(SID, {load, Modules}). check([Id, File| IncludeDirs]) -> GC = yaws_config:make_default_gconf(false, undefined), GC2 = GC#gconf{include_dir = lists:map(fun(X) -> atom_to_list(X) end, IncludeDirs), id = atom_to_list(Id) }, yaws_server:setup_dirs(GC2), put(sc, #sconf{}), put(gc, GC2), put(use_yfile_name, true), case yaws_compile:compile_file(atom_to_list(File)) of {ok, [{errors, 0}| _Spec]} -> timer:sleep(100),erlang:halt(0); _Other -> timer:sleep(100),erlang:halt(1) end. %% control a daemon http/traffic tracer trace([What, SID]) -> actl(SID, {trace, What}). debug_dump([SID]) -> actl(SID, debug_dump). stats([SID]) -> actl(SID, stats). running_config([SID]) -> actl(SID, running_config). configtest([File]) -> Env = #env{debug = false, conf = {file, File}}, case catch yaws_config:load(Env) of {ok, _GC, _SCs} -> io:format("Syntax OK~n"), timer:sleep(100),erlang:halt(0); {error, Error} -> io:format("Syntax error in file ~p:~n~s~n", [File, Error]), timer:sleep(100),erlang:halt(1); Other -> io:format("Syntax error in file ~p:~n~p~n", [File, Other]), timer:sleep(100),erlang:halt(1) end. yaws-2.0.2/src/yaws_sup.erl0000664000175000017500000001242312605311412012563 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_sup.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 16 Jan 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws_sup). -author('klacke@bluetail.com'). -include("../include/yaws.hrl"). -behaviour(supervisor). %% External exports -export([start_link/0]). %% supervisor callbacks -export([init/1]). -export([get_app_args/0, child_specs/0]). -import(lists, [member/2]). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). %%%---------------------------------------------------------------------- %%% Callback functions from supervisor %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- init([]) -> ChildSpecs = child_specs(), %% The idea behind this is if we're running in an embedded env, %% typically the supervisor above us wants to control the restarts. %% %% If we're running standalone --heart can restart the entire node %% If heart is not used, we die. %% 0, 1 means that we never want supervisor restarts {ok,{{one_for_all, 0, 1}, ChildSpecs}}. %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- child_specs() -> YawsLog = {yaws_log, {yaws_log, start_link, []}, permanent, 5000, worker, [yaws_log]}, YawsTrace = {yaws_trace, {yaws_trace, start_link, []}, permanent, 5000, worker, [yaws_trace]}, YawsServArgs = [_Env = get_app_args()], YawsServ = {yaws_server, {yaws_server, start_link, YawsServArgs}, permanent, 120000, worker, [yaws_server]}, %% and this guy will restart auxiliary procs that can fail Sup = {yaws_sup_restarts, {yaws_sup_restarts, start_link, []}, transient, infinity, supervisor, [yaws_sup_restarts]}, [YawsLog, YawsTrace, YawsServ, Sup]. %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- get_app_args() -> AS=init:get_arguments(), Debug = case application:get_env(yaws, debug) of undefined -> member({yaws, ["debug"]}, AS); {ok, Val} -> Val end, Trace = case application:get_env(yaws, trace) of undefined -> case {member({yaws, ["trace", "http"]}, AS), member({yaws, ["trace", "traffic"]}, AS)} of {true, _} -> {true, http}; {_, true} -> {true, traffic}; _ -> false end; {ok, http} -> {true, http}; {ok, traffic} -> {true, traffic}; _ -> false end, TraceOutput = case application:get_env(yaws, traceoutput) of undefined -> member({yaws, ["traceoutput"]}, AS); {ok, Val3} -> Val3 end, Conf = case application:get_env(yaws, conf) of undefined -> find_c(AS); {ok, File} -> {file, File} end, RunMod = case application:get_env(yaws, runmod) of undefined -> find_runmod(AS); {ok,Mod} -> {ok,Mod} end, Embedded = case application:get_env(yaws, embedded) of undefined -> false; {ok, Emb} -> Emb end, Id = case application:get_env(yaws, id) of undefined -> "default"; {ok, Id0} when is_atom(Id0) -> atom_to_list(Id0); {ok, Id0} -> Id0 end, #env{debug = Debug, trace = Trace, traceoutput = TraceOutput, conf = Conf, runmod = RunMod, embedded = Embedded, id = Id}. %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- find_c([{conf, [File]} |_]) -> {file, File}; find_c([_|T]) -> find_c(T); find_c([]) -> false. %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- find_runmod([{runmod, [Mod]} |_]) -> {ok,l2a(Mod)}; find_runmod([_|T]) -> find_runmod(T); find_runmod([]) -> false. %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- l2a(L) when is_list(L) -> list_to_atom(L); l2a(A) when is_atom(A) -> A. yaws-2.0.2/src/yaws_appdeps.hrl.in0000664000175000017500000000004412605311412014014 00000000000000-define(YAWS_APPDEPS, "@APPDEPS@"). yaws-2.0.2/src/yaws_appmod_fcgi.erl0000664000175000017500000000051112605311412014217 00000000000000%%% File : yaws_appmod_fcgi.erl %%% Author : Bruno Rijsman %%% Description : Application module for FastCGI virtual paths. %%% Created : 9 Jul 2009 -module(yaws_appmod_fcgi). -export([out/1]). -include("../include/yaws_api.hrl"). out(Arg) -> yaws_cgi:call_fcgi_responder(Arg). yaws-2.0.2/src/yaws_outmod.erl0000664000175000017500000000463112605311412013265 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_outmod.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 4 Nov 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws_outmod). -author('klacke@hyber.org'). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -export([out401/3, out404/3, out404/1, out/1, crashmsg/3]). %% The default error 404 error delivery module %% This function can be used to generate %% a special page on 404's (it doesn't even have to be a 404) out404(Arg) -> out404(Arg, get(gc), get(sc)). out404(Arg, GC, SC) -> Req = Arg#arg.orig_req, {abs_path, Path} = Req#http_request.path, B = not_found_body(Path, GC, SC), [{status, 404}, {header, {content_type, "text/html"}}, {header, {connection, "close"}}, {html, B}]. %% The default error 401 error delivery module %% This function can be used to generate %% a special page on 401's (it doesn't even have to be a 401) out401(_Arg, _Auth, _Realm) -> {ehtml, [{html,[], [ {body, [], [{h1,[], "401 authentication needed"} ] } ] } ] }. %% Deprecated, out401/3 will be used out(_Arg) -> {ehtml, [{html,[], [ {body, [], [{h1,[], "401 authentication needed"} ] } ] } ] }. not_found_body(Path, _GC, _SC) -> L = ["" "" "404 Not Found" "" "

Not Found

" "The requested URL ", yaws_api:htmlize(Path), " was not found on this server.

" "


", yaws:address(), " " ], list_to_binary(L). %% possibility to customize crash messages, %% while developing %% it's extremely convenient to get the crash messages in the browser, %% however not in production :-) %% This function can only return an {ehtml, EH} or an {html, HTML} %% value, no status codes, no headers etc. crashmsg(_Arg, _SC, L) -> error_logger:format("~s", [L]), {ehtml, [{h2, [], "Internal error, yaws code crashed"}, {br}, {hr}, {pre, [], yaws_api:htmlize(L)}, {hr}]}. yaws-2.0.2/src/yaws_multipart.erl0000664000175000017500000002053012605311412013773 00000000000000-module(yaws_multipart). -export([read_multipart_form/2]). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -record(upload, { fd, filename, fixed_filename, last = false, param_name, param_running_value, params, running_file_size = 0, max_file_size, no_temp_file, temp_dir = yaws:tmpdir("/tmp"), temp_file, headers = [], data_type = list }). read_multipart_form(A, Options) when A#arg.state == undefined -> State = #upload{params = dict:new()}, NewState = read_options(Options,State), multipart(A, NewState); read_multipart_form(A, _Options) -> multipart(A, A#arg.state). read_options([], State) -> State; read_options([Option|Rest], State) -> NewState = case Option of {max_file_size, SizeInBytes} -> State#upload{max_file_size = SizeInBytes}; no_temp_file -> State#upload{no_temp_file = true}; {temp_file, FullPath} -> State#upload{fixed_filename = FullPath}; {temp_dir, Dir} -> true = filelib:is_dir(Dir), State#upload{temp_dir = Dir}; list -> State#upload{data_type = list}; binary -> State#upload{data_type = binary} end, read_options(Rest, NewState). multipart(A, State) -> Parse = yaws_api:parse_multipart_post(A, [State#upload.data_type]), case Parse of {cont, Cont, Res} -> case add_file_chunk(A, Res, State) of {done, NewState} -> {done, NewState#upload.params}; {cont, NewState} -> {get_more, Cont, NewState}; Error={error, _Reason} -> Error end; {result, Res} -> case add_file_chunk(A, Res, State#upload{last=true}) of {done, S2} -> {done,S2#upload.params}; Error={error, _Reason} -> Error end; Error={error, _Reason} -> Error end. add_file_chunk(A, [{part_body, Data}|Res], State) -> add_file_chunk(A, [{body, Data}|Res], State); add_file_chunk(_A, [], State) when State#upload.last == true -> {done, close_previous_param(State)}; add_file_chunk(_A, [], State) -> {cont, State}; add_file_chunk(A, [{head, {_Name, Opts}}|Res], State ) -> S1 = close_previous_param(State), S2 = lists:foldl( fun({"filename", Fname0}, RunningState) -> case create_temp_file(State) of [undefined, undefined] -> %% values will be stored in memory as %% dictated by state#upload.no_temp_file RunningState#upload{ filename = Fname0, param_running_value = undefined, running_file_size = 0}; [Fname, Fd] -> RunningState#upload{ fd = Fd, filename = Fname0, temp_file = Fname, param_running_value = undefined, running_file_size = 0} end; ({"name", ParamName}, RunningState) -> RunningState#upload{ param_name = ParamName, param_running_value = undefined}; (HdrVal, RunningState) -> RunningState#upload{ headers = [HdrVal | RunningState#upload.headers]} end, S1, Opts), add_file_chunk(A,Res,S2); add_file_chunk(A, [{body, Data}|Res],State) when State#upload.fd /= undefined -> NewSize = compute_new_size(State,Data), Check = check_param_size(State, NewSize), case Check of ok -> ok = file:write(State#upload.fd, Data), add_file_chunk(A, Res, State#upload{running_file_size = NewSize}); Error={error, _Reason} -> Error end; add_file_chunk(A, [{body, Data}|Res], State) -> NewSize = compute_new_size(State,Data), Check = check_param_size(State, NewSize), case Check of ok -> NewState = case State#upload.param_running_value of undefined -> State#upload{param_running_value = Data}; PrevValue -> NewData = compute_new_value(PrevValue, Data), State#upload{param_running_value = NewData} end, add_file_chunk(A, Res,NewState#upload{running_file_size = NewSize}); Error={error, _Reason} -> Error end. create_temp_file(State) -> case State#upload.no_temp_file of undefined -> FilePath = case State#upload.fixed_filename of undefined -> {A, B, C} = yaws:unique_triple(), FileName = yaws:join_sep(["yaws", integer_to_list(A), integer_to_list(B), integer_to_list(C)], "_"), filename:join([State#upload.temp_dir, FileName]); Filename -> Filename end, {ok,Fd} = file:open(FilePath, [write,binary]), [FilePath, Fd]; true -> [undefined, undefined] end . close_previous_param(#upload{param_name = undefined} = State) -> State; close_previous_param(#upload{param_name = ParamName} = State) -> S2 = case State#upload.filename of undefined -> ParamValue = State#upload.param_running_value, State#upload{ params = dict:store(ParamName, ParamValue, State#upload.params)}; _ -> ParamInfo = [{"filename", State#upload.filename}], ParamInfo2 = case State#upload.fd of undefined -> lists:append( ParamInfo, [{value, State#upload.param_running_value}]); Fd -> file:close(Fd), lists:append(ParamInfo, [{temp_file, State#upload.temp_file}]) end, ParamInfo3 = lists:append(ParamInfo2, State#upload.headers), State#upload{ filename = undefined, fd = undefined, temp_file= undefined, running_file_size = 0, params = dict:store(ParamName, ParamInfo3, State#upload.params) } end, S2#upload{param_name = undefined, param_running_value = undefined, headers = []}. compute_new_size(State, Data) -> case Data of undefined -> State#upload.running_file_size; _ -> State#upload.running_file_size + iolist_size(Data) end. check_param_size(State, NewSize) -> case State#upload.max_file_size of undefined -> ok; MaxSizeInBytes -> case NewSize > MaxSizeInBytes of true -> {error, io_lib:format("~p is too large", [State#upload.param_name])}; false -> ok end end. compute_new_value(PrevValue, NewData) -> case NewData of Data when is_binary(NewData) -> <>; Data when is_list(NewData) -> PrevValue ++ Data end. yaws-2.0.2/src/json2.erl0000664000175000017500000006341012605311412011746 00000000000000%%% Copyright (c) 2005-2006, A2Z Development USA, Inc. All Rights Reserved. %%% %%% The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is A2Z Development USA, Inc. %%% All Rights Reserved. -module(json2). -export([encode/1, decode_string/1, decode/2]). -export([is_obj/1, obj_new/0, obj_fetch/2, obj_find/2, obj_is_key/2]). -export([obj_store/3, obj_from_list/1, obj_fold/3]). -export([test/0]). -author("Jim Larson , Robert Wai-Chi Chu "). -author("Gaspar Chilingarov , Gurgen Tumanyan "). -author("Steve Vinoski "). %%% JavaScript Object Notation ("JSON", http://www.json.org) is a simple %%% data syntax meant as a lightweight alternative to other representations, %%% such as XML. JSON is natively supported by JavaScript, but many %%% other languages have conversion libraries available. %%% %%% This module translates JSON types into the following Erlang types: %%% %%% JSON Erlang %%% ---- ------ %%% number number %%% string string %%% array {array, ElementList} %%% object tagged proplist with string keys (i.e. {struct, PropList} ) %%% true, false, null atoms 'true', 'false', and 'null' %%% %%% Character Sets: the external representation, and the internal %%% representation of strings, are lists of UTF-8 code units. %%% %%% Numbers: Thanks to Erlang's bignums, JSON-encoded integers of any %%% size can be parsed. Conversely, extremely large integers may %%% be JSON-encoded. This may cause problems for interoperability %%% with JSON parsers which can't handle arbitrary-sized integers. %%% Erlang's floats are of fixed precision and limited range, so %%% syntactically valid JSON floating-point numbers could silently %%% lose precision or noisily cause an overflow. However, most %%% other JSON libraries are likely to behave in the same way. %%% %%% Strings: If we represented JSON string data as Erlang binaries, %%% we would have to choose a particular unicode format. Instead, %%% we use lists of UTF-16 code units, which applications may then %%% change to binaries in their application-preferred manner. %%% %%% Arrays: Because of the string decision above, and Erlang's %%% lack of a distinguished string datatype, JSON arrays map %%% to {array, ArrayElementList}, where ArrayElementList -> list. %%% %%% Objects: Though not explicitly stated in the JSON "spec", %%% JSON's JavaScript heritage mandates that member names must %%% be unique within an object. The object/tuple ambiguity is %%% not a problem, since the atom 'struct' is not an %%% allowable value. Object keys may be atoms or strings on %%% encoding but are always decoded as strings. %%% %%% ENCODING %% Encode an erlang number, string, tuple, or object to JSON syntax, as a %% possibly deep list of UTF-8 code units, throwing a runtime error in the %% case of un-convertible input. %% Note: object keys may be either strings or atoms. encode(true) -> "true"; encode(false) -> "false"; encode(null) -> "null"; encode(undefined) -> "null"; encode(B) when is_binary(B) -> encode_string(B); encode(I) when is_integer(I) -> integer_to_list(I); encode(F) when is_float(F) -> float_to_list(F); encode(L) when is_list(L) -> case is_string(L) of yes -> encode_string(L); unicode -> encode_string(xmerl_ucs:to_utf8(L)); no -> encode({array, L}) end; encode({array, Props}) when is_list(Props) -> encode_array(Props); encode({struct, Props} = T) when is_list(Props) -> encode_object(T); encode(Bad) -> exit({json_encode, {bad_term, Bad}}). %% Encode an Erlang string to JSON. %% Accumulate strings in reverse. encode_string(B) when is_binary(B) -> encode_string(binary_to_list(B)); encode_string(S) -> encode_string(S, [$"]). encode_string([], Acc) -> lists:reverse([$" | Acc]); encode_string([C | Cs], Acc) -> case C of $" -> encode_string(Cs, [$", $\\ | Acc]); % (don't escape solidus on encode) $\\ -> encode_string(Cs, [$\\, $\\ | Acc]); $\b -> encode_string(Cs, [$b, $\\ | Acc]); % note missing \ $\f -> encode_string(Cs, [$f, $\\ | Acc]); $\n -> encode_string(Cs, [$n, $\\ | Acc]); $\r -> encode_string(Cs, [$r, $\\ | Acc]); $\t -> encode_string(Cs, [$t, $\\ | Acc]); C when C >= 0, C < $\s -> % Control characters must be unicode-encoded. Hex = lists:flatten(io_lib:format("~4.16.0b", [C])), encode_string(Cs, lists:reverse(Hex) ++ "u\\" ++ Acc); % " C when C =< 16#FFFF -> encode_string(Cs, [C | Acc]); _ -> exit({json_encode, {bad_char, C}}) end. %% Encode an Erlang object as a JSON object, allowing string or atom keys. %% Note that order is irrelevant in both internal and external object %% representations. Nevertheless, the output will respect the order %% of the input. encode_object({struct, _Props} = Obj) -> M = obj_fold(fun({Key, Value}, Acc) -> S = case Key of B when is_binary(B) -> encode_string(B); L when is_list(L) -> case is_string(L) of yes -> encode_string(L); unicode -> encode_string(xmerl_ucs:to_utf8(L)); no -> exit({json_encode, {bad_key, Key}}) end; A when is_atom(A) -> encode_string(atom_to_list(A)); _ -> exit({json_encode, {bad_key, Key}}) end, V = encode(Value), case Acc of [] -> [S, $:, V]; _ -> [Acc, $,, S, $:, V] end end, [], Obj), [${, M, $}]. %% Encode an Erlang tuple as a JSON array. %% Order *is* significant in a JSON array! encode_array(T) -> M = lists:foldl(fun(E, Acc) -> V = encode(E), case Acc of [] -> V; _ -> [Acc, $,, V] end end, [], T), [$[, M, $]]. %%% SCANNING %%% %%% Scanning funs return either: %%% {done, Result, LeftOverChars} %%% if a complete token is recognized, or %%% {more, Continuation} %%% if more input is needed. %%% Result is {ok, Term}, 'eof', or {error, Reason}. %%% Here, the Continuation is a simple Erlang string. %%% %%% Currently, error handling is rather crude - errors are recognized %%% by match failures. EOF is handled only by number scanning, where %%% it can delimit a number, and otherwise causes a match failure. %%% %%% Tokens are one of the following %%% JSON string -> erlang string %%% JSON number -> erlang number %%% true, false, null -> erlang atoms %%% { } [ ] : , -> lcbrace rcbrace lsbrace rsbrace colon comma token([]) -> {more, []}; token(eof) -> {done, eof, []}; token("true" ++ Rest) -> {done, {ok, true}, Rest}; token("tru") -> {more, "tru"}; token("tr") -> {more, "tr"}; token("t") -> {more, "t"}; token("false" ++ Rest) -> {done, {ok, false}, Rest}; token("fals") -> {more, "fals"}; token("fal") -> {more, "fal"}; token("fa") -> {more, "fa"}; token("f") -> {more, "f"}; token("null" ++ Rest) -> {done, {ok, null}, Rest}; token("nul") -> {more, "nul"}; token("nu") -> {more, "nu"}; token("n") -> {more, "n"}; token([C | Cs] = Input) -> case C of $\s -> token(Cs); % eat whitespace $\t -> token(Cs); % eat whitespace $\n -> token(Cs); % eat whitespace $\r -> token(Cs); % eat whitespace $" -> scan_string(Input); $- -> scan_number(Input); D when D >= $0, D =< $9-> scan_number(Input); ${ -> {done, {ok, lcbrace}, Cs}; $} -> {done, {ok, rcbrace}, Cs}; $[ -> {done, {ok, lsbrace}, Cs}; $] -> {done, {ok, rsbrace}, Cs}; $: -> {done, {ok, colon}, Cs}; $, -> {done, {ok, comma}, Cs}; _ -> {done, {error, {bad_char, C}}, Cs} end. scan_string([$" | Cs] = Input) -> scan_string(Cs, [], Input). %% Accumulate in reverse order, save original start-of-string for continuation. scan_string([], _, X) -> {more, X}; scan_string(eof, _, X) -> {done, {error, missing_close_quote}, X}; scan_string([$" | Rest], A, _) -> {done, {ok, lists:reverse(A)}, Rest}; scan_string([$\\], _, X) -> {more, X}; scan_string([$\\, $u, U1, U2, U3, U4 | Rest], A, X) -> scan_string(Rest, lists:reverse(uni_char([U1, U2, U3, U4]))++A, X); scan_string([$\\, $u | _], _, X) -> {more, X}; scan_string([$\\, C | Rest], A, X) -> scan_string(Rest, [esc_to_char(C) | A], X); scan_string([C | Rest], A, X) -> scan_string(Rest, [C | A], X). %% Given a list of hex characters, convert to the corresponding integer. uni_char(HexList) -> UC = erlang:list_to_integer(HexList, 16), binary_to_list(unicode:characters_to_binary([UC],utf8)). esc_to_char($") -> $"; esc_to_char($/) -> $/; esc_to_char($\\) -> $\\; esc_to_char($b) -> $\b; esc_to_char($f) -> $\f; esc_to_char($n) -> $\n; esc_to_char($r) -> $\r; esc_to_char($t) -> $\t. scan_number([]) -> {more, []}; scan_number(eof) -> {done, {error, incomplete_number}, []}; scan_number([$-, $- | _Ds]) -> {done, {error, invalid_number}, []}; scan_number([$- | Ds] = Input) -> case scan_number(Ds) of {more, _Cont} -> {more, Input}; {done, {ok, N}, CharList} -> {done, {ok, -1 * N}, CharList}; {done, Other, Chars} -> {done, Other, Chars} end; scan_number([D | Ds] = Input) when D >= $0, D =< $9 -> scan_number(Ds, D - $0, Input). %% Numbers don't have a terminator, so stop at the first non-digit, %% and ask for more if we run out. scan_number([], _A, X) -> {more, X}; scan_number(eof, A, _X) -> {done, {ok, A}, eof}; scan_number([$.], _A, X) -> {more, X}; scan_number([$., D | Ds], A, X) when D >= $0, D =< $9 -> scan_fraction([D | Ds], A, X); scan_number([D | Ds], A, X) when A > 0, D >= $0, D =< $9 -> % Note that nonzero numbers can't start with "0". scan_number(Ds, 10 * A + (D - $0), X); scan_number([D | Ds], A, X) when D == $E; D == $e -> scan_exponent_begin(Ds, integer_to_list(A) ++ ".0", X); scan_number([D | _] = Ds, A, _X) when D < $0; D > $9 -> {done, {ok, A}, Ds}. scan_fraction(Ds, I, X) -> scan_fraction(Ds, [], I, X). scan_fraction([], _Fs, _I, X) -> {more, X}; scan_fraction(eof, Fs, I, _X) -> R = list_to_float(lists:append([integer_to_list(I), ".", lists:reverse(Fs)])), {done, {ok, R}, eof}; scan_fraction([D | Ds], Fs, I, X) when D >= $0, D =< $9 -> scan_fraction(Ds, [D | Fs], I, X); scan_fraction([D | Ds], Fs, I, X) when D == $E; D == $e -> R = lists:append([integer_to_list(I), ".", lists:reverse(Fs)]), scan_exponent_begin(Ds, R, X); scan_fraction(Rest, Fs, I, _X) -> R = list_to_float(lists:append([integer_to_list(I), ".", lists:reverse(Fs)])), {done, {ok, R}, Rest}. scan_exponent_begin(Ds, R, X) -> scan_exponent_begin(Ds, [], R, X). scan_exponent_begin([], _Es, _R, X) -> {more, X}; scan_exponent_begin(eof, _Es, _R, X) -> {done, {error, missing_exponent}, X}; scan_exponent_begin([D | Ds], Es, R, X) when D == $-; D == $+; D >= $0, D =< $9 -> scan_exponent(Ds, [D | Es], R, X). scan_exponent([], _Es, _R, X) -> {more, X}; scan_exponent(eof, Es, R, _X) -> X = list_to_float(lists:append([R, "e", lists:reverse(Es)])), {done, {ok, X}, eof}; scan_exponent([D | Ds], Es, R, X) when D >= $0, D =< $9 -> scan_exponent(Ds, [D | Es], R, X); scan_exponent(Rest, Es, R, _X) -> X = list_to_float(lists:append([R, "e", lists:reverse(Es)])), {done, {ok, X}, Rest}. %%% PARSING %%% %%% The decode function takes a char list as input, but %%% interprets the end of the list as only an end to the available %%% input, and returns a "continuation" requesting more input. %%% When additional characters are available, they, and the %%% continuation, are fed into decode/2. You can use the atom 'eof' %%% as a character to signal a true end to the input stream, and %%% possibly flush out an unfinished number. The decode_string/1 %%% function appends 'eof' to its input and calls decode/1. %%% %%% Parsing and scanning errors are handled only by match failures. %%% The external caller must take care to wrap the call in a "catch" %%% or "try" if better error-handling is desired. Eventually parse %%% or scan errors will be returned explicitly with a description, %%% and someday with line numbers too. %%% %%% The parsing code uses a continuation-passing style to allow %%% for the parsing to suspend at any point and be resumed when %%% more input is available. %%% See http://en.wikipedia.org/wiki/Continuation_passing_style %% Return the first JSON value decoded from the input string. %% The string must contain at least one complete JSON value. decode_string(CharList) -> {done, V, _} = decode([], CharList ++ eof), V. %% Attempt to decode a JSON value from the input string %% and continuation, using empty list for the initial continuation. %% Return {done, Result, LeftoverChars} if a value is recognized, %% or {more, Continuation} if more input characters are needed. %% The Result can be {ok, Value}, eof, or {error, Reason}. %% The Continuation is then fed as an argument to decode/2 when %% more input is available. %% Use the atom 'eof' instead of a char list to signal %% a true end to the input, and may flush a final number. decode([], CharList) -> decode(first_continuation(), CharList); decode(Continuation, CharList) -> {OldChars, Kt} = Continuation, get_token(OldChars ++ CharList, Kt). first_continuation() -> {[], fun (eof, Cs) -> {done, eof, Cs}; (T, Cs) -> parse_value(T, Cs, fun(V, C2) -> {done, {ok, V}, C2} end) end}. %% Continuation Kt must accept (TokenOrEof, Chars) get_token(Chars, Kt) -> case token(Chars) of {done, {ok, T}, Rest} -> Kt(T, Rest); {done, eof, Rest} -> Kt(eof, Rest); {done, {error, Reason}, Rest} -> {done, {error, Reason}, Rest}; {more, X} -> {more, {X, Kt}} end. %% Continuation Kv must accept (Value, Chars) parse_value(eof, C, _Kv) -> {done, {error, premature_eof}, C}; parse_value(true, C, Kv) -> Kv(true, C); parse_value(false, C, Kv) -> Kv(false, C); parse_value(null, C, Kv) -> Kv(null, C); parse_value(S, C, Kv) when is_list(S) -> Kv(S, C); parse_value(N, C, Kv) when is_number(N) -> Kv(N, C); parse_value(lcbrace, C, Kv) -> parse_object(C, Kv); parse_value(lsbrace, C, Kv) -> parse_array(C, Kv); parse_value(_, C, _Kv) -> {done, {error, syntax_error}, C}. %% Continuation Kv must accept (Value, Chars) parse_object(Chars, Kv) -> get_token(Chars, fun(T, C2) -> Obj = obj_new(), case T of rcbrace -> Kv(Obj, C2); % empty object _ -> parse_object(Obj, T, C2, Kv) % token must be string end end). parse_object(_Obj, eof, C, _Kv) -> {done, {error, premature_eof}, C}; parse_object(Obj, S, C, Kv) when is_list(S) -> % S is member name get_token(C, fun (colon, C2) -> parse_object2(Obj, S, C2, Kv); (T, C2) -> {done, {error, {expecting_colon, T}}, C2} end); parse_object(_Obj, M, C, _Kv) -> {done, {error, {member_name_not_string, M}}, C}. parse_object2(Obj, S, C, Kv) -> get_token(C, fun (eof, C2) -> {done, {error, premature_eof}, C2}; (T, C2) -> parse_value(T, C2, fun(V, C3) -> % V is member value Obj2 = obj_store(S, V, Obj), get_token(C3, fun (rcbrace, C4) -> % "}" end of object {struct, PropList1} = Obj2, Kv({struct, lists:reverse(PropList1)}, C4); (comma, C4) -> % "," another member follows get_token(C4, fun(T3, C5) -> parse_object(Obj2, T3, C5, Kv) end); (eof, C4) -> {done, {error, premature_eof}, C4}; (T2, C4) -> {done, {error, {expecting_comma_or_curly, T2}}, C4} end) end) end). %% Continuation Kv must accept (Value, Chars) parse_array(C, Kv) -> get_token(C, fun (eof, C2) -> {done, {error, premature_eof}, C2}; (rsbrace, C2) -> Kv({array, []}, C2); % empty array (T, C2) -> parse_array([], T, C2, Kv) end). parse_array(E, T, C, Kv) -> parse_value(T, C, fun(V, C2) -> E2 = [V | E], get_token(C2, fun (rsbrace, C3) -> % "]" end of array Kv({array, lists:reverse(E2)}, C3); (comma, C3) -> % "," another value follows get_token(C3, fun(T3, C4) -> parse_array(E2, T3, C4, Kv) end); (eof, C3) -> {done, {error, premature_eof}, C3}; (T2, C3) -> {done, {error, {expecting_comma_or_close_array, T2}}, C3} end) end). %%% OBJECTS %%% %%% We'll use tagged property lists as the internal representation %%% of JSON objects. Unordered lists perform worse than trees for %%% lookup and modification of members, but we expect objects to be %%% have only a few members. Lists also print better. %% Is this a proper JSON object representation? is_obj({struct, Props}) when is_list(Props) -> lists:all(fun ({Member, _Value}) when is_atom(Member); is_list(Member) -> true; (_) -> false end, Props); is_obj(_) -> false. %% Create a new, empty object. obj_new() -> {struct, []}. %% Fetch an object member's value, expecting it to be in the object. %% Return value, runtime error if no member found with that name. obj_fetch(Key, {struct, Props}) when is_list(Props) -> case proplists:get_value(Key, Props) of undefined -> exit({struct_no_key, Key}); Value -> Value end. %% Fetch an object member's value, or indicate that there is no such member. %% Return {ok, Value} or 'error'. obj_find(Key, {struct, Props}) when is_list(Props) -> case proplists:get_value(Key, Props) of undefined -> error; Value -> {ok, Value} end. obj_is_key(Key, {struct, Props}) -> proplists:is_defined(Key, Props). %% Store a new member in an object. Returns a new object. obj_store(Key, Value, {struct, Props}) when is_list(Props) -> {struct, [{Key, Value} | proplists:delete(Key, Props)]}. %% Create an object from a list of Key/Value pairs. obj_from_list(Props) -> Obj = {struct, Props}, case is_obj(Obj) of true -> Obj; false -> exit(json_bad_object) end. %% Fold Fun across object, with initial accumulator Acc. %% Fun should take (Value, Acc) as arguments and return Acc. obj_fold(Fun, Acc, {struct, Props}) -> lists:foldl(Fun, Acc, Props). is_string([]) -> yes; is_string(List) -> is_string(List, non_unicode). is_string([C|Rest], non_unicode) when is_integer(C), C >= 0, C =< 255 -> is_string(Rest, non_unicode); is_string([C|Rest], _) when is_integer(C), C =< 65000 -> is_string(Rest, unicode); is_string([], non_unicode) -> yes; is_string([], unicode) -> unicode; is_string(_, _) -> no. %%% TESTING %%% %%% We can't expect to round-trip from JSON -> Erlang -> JSON, %%% due to the degrees of freedom in the JSON syntax: whitespace, %%% and ordering of object members. We can, however, expect to %%% round-trip from Erlang -> JSON -> Erlang, so the JSON parsing %%% tests will in fact test the Erlang equivalence of the %%% JSON -> Erlang -> JSON -> Erlang coding chain. %% Test driver. Return 'ok' or {failed, Failures}. test() -> E2Js = e2j_test_vec(), Failures = lists:foldl( fun({E, J}, Fs) -> case (catch test_e2j(E, J)) of ok -> case (catch round_trip(E)) of ok -> case (catch round_trip_one_char(E)) of ok -> Fs; Reason -> [{round_trip_one_char, E, Reason} | Fs] end; Reason -> [{round_trip, E, Reason} | Fs] end; Reason -> [{erlang_to_json, E, J, Reason} | Fs] end; (end_of_tests, Fs) -> Fs end, [], E2Js), case Failures of [] -> ok; _ -> {failed, Failures} end. %% Test for conversion from Erlang to JSON. Note that unequal strings %% may represent equal JSON data, due to discretionary whitespace, %% object member order, trailing zeroes in floating point, etc. %% Legitimate changes to the encoding routines may require tweaks to %% the reference JSON strings in e2j_test_vec(). %% This clause handles floats specially due to the need for fuzzy matching %% to avoid slight differences due to conversions. Rather than direct %% comparison as done in the more general clause below, here we allow a %% small relative difference between expected and actual. test_e2j(E, J) when is_float(E) -> J2 = lists:flatten(encode(E)), E2 = list_to_float(J2), E1 = list_to_float(J), Rel = abs(E2 - E1)/E, true = Rel < 0.005, ok; test_e2j(E, J) -> J2 = lists:flatten(encode(E)), J = J2, % raises error if unequal ok. %% Test that Erlang -> JSON -> Erlang round-trip yields equivalent term. round_trip(E) -> J2 = lists:flatten(encode(E)), {ok, E2} = decode_string(J2), true = equiv(E, E2), % raises error if false ok. %% Round-trip with one character at a time to test all continuations. round_trip_one_char(E) -> J = lists:flatten(encode(E)), {done, {ok, E2}, _} = lists:foldl(fun(C, Ret) -> case Ret of {done, _, _} -> Ret; {more, Cont} -> decode(Cont, [C]) end end, {more, first_continuation()}, J ++ [eof]), true = equiv(E, E2), % raises error if false ok. %% Test for equivalence of Erlang terms. %% Due to arbitrary order of construction, equivalent objects might %% compare unequal as erlang terms, so we need to carefully recurse %% through aggregates (arrays and objects). equiv({struct, Props1}, {struct, Props2}) -> equiv_object(Props1, Props2); equiv({array, ArrayList1}, {array, ArrayList2}) -> equiv_array(ArrayList1, ArrayList2); equiv(N1, N2) when is_number(N1), is_number(N2) -> N1 == N2; equiv(S1, S2) when is_list(S1), is_list(S2) -> case {is_string(S1), is_string(S2)} of {unicode, unicode} -> xmerl_ucs:to_utf8(S1) == xmerl_ucs:to_utf8(S2); {unicode, _} -> xmerl_ucs:to_utf8(S1) == S2; {_, unicode} -> S1 == xmerl_ucs:to_utf8(S2); _ -> S1 == S2 end; equiv(true, true) -> true; equiv(false, false) -> true; equiv(null, null) -> true. %% Object representation and traversal order is unknown. %% Use the sledgehammer and sort property lists. equiv_object(Props1, Props2) -> L1 = lists:keysort(1, Props1), L2 = lists:keysort(1, Props2), Pairs = lists:zip(L1, L2), true = lists:all(fun({{K1, V1}, {K2, V2}}) -> equiv(K1, K2) and equiv(V1, V2) end, Pairs). %% Recursively compare array elements for equivalence. equiv_array([], []) -> true; equiv_array(A1, A2) when length(A1) == length(A2) -> lists:all(fun({E1,E2}) -> equiv(E1, E2) end, lists:zip(A1, A2)). e2j_test_vec() -> [ {1, "1"}, {3.1416, "3.14160"}, % text representation may truncate, trail zeroes {-1, "-1"}, {-3.1416, "-3.14160"}, {12.0e10, "1.20000e+11"}, {1.234E+10, "1.23400e+10"}, {-1.234E-10, "-1.23400e-10"}, {"foo", "\"foo\""}, {"foo" ++ [500] ++ "bar", [$", $f, $o, $o, $\307, $\264, $b, $a, $r, $"]}, {"foo" ++ [5] ++ "bar", "\"foo\\u0005bar\""}, {"", "\"\""}, {[], "\"\""}, {"\n\n\n", "\"\\n\\n\\n\""}, {obj_new(), "{}"}, {obj_from_list([{"foo", "bar"}]), "{\"foo\":\"bar\"}"}, {obj_from_list([{"foo", "bar"}, {"baz", 123}]), "{\"foo\":\"bar\",\"baz\":123}"}, {{array, []}, "[]"}, {{array, [{array, []}]}, "[[]]"}, {{array, [1, "foo"]}, "[1,\"foo\"]"}, % json array in a json object {obj_from_list([{"foo", {array, [123]}}]), "{\"foo\":[123]}"}, % json object in a json object {obj_from_list([{"foo", obj_from_list([{"bar", true}])}]), "{\"foo\":{\"bar\":true}}"}, % fold evaluation order {obj_from_list([{"foo", {array, []}}, {"bar", obj_from_list([{"baz", true}])}, {"alice", "bob"}]), "{\"foo\":[],\"bar\":{\"baz\":true},\"alice\":\"bob\"}"}, % json object in a json array {{array, [-123, "foo", obj_from_list([{"bar", {array, []}}]), null]}, "[-123,\"foo\",{\"bar\":[]},null]"}, end_of_tests ]. %%% TODO: %%% %%% Measure the overhead of the CPS-based parser by writing a conventional %%% scanner-parser that expects all input to be available. %%% %%% Allow a compile-time option to decode object member names as atoms, %%% to reduce the internal representation overheads when communicating %%% with trusted peers. yaws-2.0.2/src/yaws_debug.erl0000664000175000017500000004672012605311412013051 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_debug.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 7 Feb 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws_debug). -author('klacke@hyber.org'). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). -export([typecheck/3, format_record/3, assert/4, format/2,format/3, derror/2, dinfo/2, mktags/0, xref/1, pids/0, eprof/0, check_headers/1, nobin/1, do_debug_dump/1 ]). typecheck([{record, Rec, X} | Tail], File, Line) when is_atom(X), element(1, Rec) == X -> typecheck(Tail, File, Line); typecheck([{int, Int} |Tail], File, Line) when is_integer(Int) -> typecheck(Tail, File, Line); typecheck([Err|_], File, Line) -> debug_format(user, "TC ERROR ~s:~w:~n~p", [File, Line, Err]), erlang:error(tcerr); typecheck([], _,_) -> ok. %% returns {record, RecName, [Field1, Val1} .....] format_record(Record, Name, Fields) -> case tuple_to_list(Record) of [Name | Rest] -> io_lib:format("record ~w\n~s", [Name, format_record(Rest, Fields)]); _X -> ?Debug("Bad record ~p is not ~p~n", [_X, Name]), "badrecord" end. format_record([], []) -> []; format_record([Val|Vals], [F|Fs]) when is_integer(Val); Val == []; is_atom(Val); is_float(Val)-> [io_lib:format(" ~w = ~w\n", [F,Val]), format_record(Vals, Fs)]; format_record([Val|Vals], [F|Fs]) -> case is_string(Val) of true -> [io_lib:format(" ~w = \"~s\"\n", [F,Val]), format_record(Vals, Fs)]; false -> [io_lib:format(" ~w = ~p~n", [F, nobin(Val)]), format_record(Vals, Fs)] end. is_string(L) when is_list(L) -> lists:filter(fun(X) when is_integer(X), $A < X, X < $z -> false; (_) -> true end,L) == []; is_string(_) -> false. assert(equal,X,Y,_) when X==Y -> ok; assert(neq,X,Y,_) when X/=Y -> ok; assert(integer,X,_,_) when is_integer(X) -> ok; assert(list,X,_,_) when is_list(X) -> ok; assert({list,length,equal},X,Y,_) when is_list(X), length(X)==Y -> ok; assert(greater,X,Y,_) when is_integer(X), is_integer(Y), X>Y -> ok; assert(min,X,Y,_) when is_integer(X), is_integer(Y), X>=Y -> ok; assert(lesser,X,Y,_) when is_integer(X), is_integer(Y), X ok; assert(max,X,Y,_) when is_integer(X), is_integer(Y), X= ok; assert(interval,X,{Min,Max},_) when is_integer(X), is_integer(Min), is_integer(Max), X>=Min, Max>=X -> ok; assert('fun', Fun, _, Failure) -> case catch Fun() of true -> ok; _Other -> fail(Failure) end; assert(in,X,L,Failure) when is_list(L) -> case lists:member(X,L) of true -> ok; _ -> fail(Failure) end; assert(_,_,_,Failure) -> fail(Failure). fail({assert,File,Line,Message}) -> debug_format(user, "Assertion FAILED ~p:~p, pid ~w exiting: ~p~n", [File, Line, self(), Message]), erlang:error(assertion_failed); fail({alert,File,Line,Message}) -> debug_format(user, "Assert WARNING ~p:~p, pid ~w: ~p~n", [File, Line, self(), Message]), ok; fail({{debug,Fstr}, File,Line,Fmt, Args}) -> Str = lists:flatten( io_lib:format("~s <~p> ~s:~p, pid ~w: ~n", [Fstr, node(), filename:basename(File), Line, self()])), case (catch debug_format(user, Str ++ Fmt ++ "~n", Args)) of ok -> ok; _ -> debug_format(user, "ERROR ~p:~p: Pid ~w: (bad format)~n~p,~p~n", [File, Line, self(), Fmt, Args]), ok end; fail({format, File,Line,Fmt,Args}) -> case (catch debug_format(user, Fmt,Args)) of ok -> ok; _ -> debug_format(user, "ERROR ~p:~p: Pid ~w: (bad format)~n~p,~p~n", [File, Line, self(), Fmt, Args]), ok end. debug_format(_, F, D) -> debug_format(F, D). debug_format(F, A) -> Str = case catch io_lib:format("yaws debug: " ++ F, A) of {'EXIT', Reason} -> io_lib:format("yaws debug: F=~s A=~p (failed to format: ~p)", [F, A, Reason]); Ok -> Ok end, error_logger:info_msg(Str), catch io:format(F, A), ok. format(F, A) -> format(get(gc), F, A). format(GC, F, A) -> case ?gc_has_debug(GC) of true -> error_logger:info_msg("yaws debug:" ++ F, A); false -> ok end. derror(F, A) -> case ?gc_has_debug((get(gc))) of true -> error_logger:error_msg("yaws:" ++ F, A); false -> ok end. dinfo(F, A) -> case ?gc_has_debug((get(gc))) of true -> error_logger:info_msg("yaws:" ++ F, A); false -> ok end. mktags() -> tags:dirs(["."]), init:stop(). xref([Dir]) -> debug_format("~p~n", [xref:d(Dir)]), init:stop(). pids() -> lists:zf( fun(P) -> case process_info(P) of L when is_list(L) -> {value, {_, {M1, _,_}}} = lists:keysearch(current_function, 1, L), {value, {_, {M2, _,_}}} = lists:keysearch(initial_call, 1, L), S1= atom_to_list(M1), S2 = atom_to_list(M2), case {S1, S2} of {"yaws" ++ _, _} -> {true, P}; {_, "yaws"++_} -> {true, P}; _ -> false end; _ -> false end end, processes()). eprof() -> eprof:start(), eprof:profile(pids()), debug_format("Ok run some traffic \n", []). -define(h_check(H, Field), f_check(H#outh.Field, Field)). f_check(undefined, _Field) -> ok; f_check(Str, Field) -> case lists:reverse(lists:flatten(Str)) of [$\n, $\r , H | _Tail] -> case lists:member(H, [$\n, $\r]) of true -> error_logger:format("Bad <~p> header:~n" " ~p~nToo many newlines", [Field, Str]), exit(normal); false -> ok end; _Other -> error_logger:format("Bad <~p> header:~n" "~p~nNot ending with CRNL~n", [Field, Str]), exit(normal) end. check_headers(H) -> ?h_check(H, connection), ?h_check(H, server), ?h_check(H, location), ?h_check(H, cache_control), ?h_check(H, date), ?h_check(H, allow), ?h_check(H, last_modified), ?h_check(H, etag), ?h_check(H, content_range), ?h_check(H, content_length), ?h_check(H, content_encoding), ?h_check(H, set_cookie), ?h_check(H, transfer_encoding), ?h_check(H, www_authenticate), check_other(H#outh.other). check_other(undefined) -> ok; check_other(L0) -> L = lists:flatten(L0), case lists:dropwhile(fun(X) -> not lists:member(X, ["\r\n"]) end, L) of [] -> ok; [$\r, $\n, H | _Tail] -> case lists:member(H, [$\n, $\r]) of true -> bad_other(L); false -> ok end; _Other -> bad_other(L) end. bad_other(L) -> Bad = lists:takewhile( fun(X) -> not lists:member(X, ["\r\n"]) end, L), error_logger:format("Bad header:~p~n" "Too many newlines", [Bad]), exit(normal). nobin(X) -> case catch xnobin(X) of {'EXIT', Reason} -> error_logger:format("~p~n~p~n", [X, Reason]), erlang:error(Reason); Res -> Res end. xnobin(B) when is_binary(B) -> lists:flatten(io_lib:format("#Bin(~w)", [size(B)])); xnobin(L) when is_list(L) -> lists:map(fun(X) -> xnobin(X) end, L); xnobin(T) when is_tuple(T) -> list_to_tuple(xnobin(tuple_to_list(T))); xnobin(X) -> X. %%%%%%%%%%%%%%% debug dump %%%%%%%%%%%%%%%%%%%%%%% do_debug_dump(Socket) -> gen_version(Socket), gen_sep(Socket), %% keep proc status last, to report on hangs for the others CollectOS = gen_os(Socket), Collect = lists:foldl(fun({F, Str}, Acc) -> Ret = collect(F, Socket, Str), gen_sep(Socket), [Ret|Acc] end, CollectOS, [{fun send_status/1, "Yaws status"}, {fun send_inet/1, "Inet status"}, {proc_status_fun(), "process status"}]), lists:foreach(fun(ok) -> ok; ({pid, Pid}) -> exit(Pid, shutdown) end, Collect), ok. gen_version(Socket) -> sock_format(Socket, "Yawsvsn: ~p~n", [yaws_generated:version()]). gen_os(Socket) -> OSType = os:type(), [gen_oscmd(Socket, "uname -a"), gen_oscmd(Socket, "ifconfig -a"), gen_oscmd(Socket, top_cmd(OSType)), gen_oscmd(Socket, netstat_cmd(OSType))]. gen_oscmd(Socket, Cmd) -> F = fun(Sock) -> sock_format(Sock, "~s:~n~s~n", [Cmd, os:cmd(Cmd)]) end, Ret = collect(F, Socket, Cmd), gen_sep(Socket), Ret. %% FIXME The 'top -b -n 1' invocation is actually for version 3.2.x %% typically(?) found on Linux, while the 'top -b' is for (e.g.) version %% 3.5.x typically(?) found on *BSD. For the latter, '-b' itself means %% "run only once", '-n' is an alias for '-b', and '1' means show only %% one process. Obviously there is a problem if 3.2.x or equivalent ends %% up getting invoked w/o '-n 1', since it will loop forever... top_cmd({unix, linux}) -> "top -b -n 1"; top_cmd({unix, sunos}) -> "top -b -d 2 -s 1 || /usr/ucb/ps -auxww"; top_cmd({unix, qnx}) -> "pidin times; pidin pmem"; top_cmd({unix, darwin}) -> "top -o cpu -l 1"; top_cmd(_) -> "top -b". netstat_cmd({unix, linux}) -> "netstat -ant"; netstat_cmd({unix, freebsd}) -> "netstat -an -p tcp"; netstat_cmd({unix, sunos}) -> "netstat -an -P tcp"; netstat_cmd(_) -> "netstat -an". gen_sep(Socket) -> sock_format(Socket,"~n~s~n", [lists:duplicate(40, $*)]). proc_status_fun() -> fun(Fd) -> sock_format(Fd, "Process status:~n", []), i1(Fd, processes()) end. i1(Fd, Ps) -> Alive = lists:filter(fun palive/1, Ps), i2(Fd, Alive), case lists:filter(fun pzombie/1, Ps) of [] -> ok; Zombies -> %% Zombies is not the same as Ps-Alive, since the remote %% process that fetched Ps is included among Alive, but has %% exited (for ni/0). sock_format(Fd, "\nDead processes:\n", []), i2(Fd, Zombies) end. i2(Fd, Ps) -> iformat(Fd, "Pid", "Initial Call", "Current Function", "Reds", "Msgs", "Heap", "Stack"), {Reds,Msgs,Heap,Stack,Susp1,Susp2,MemSusp,_} = lists:foldl(fun display_info/2, {0,0,0,0,[],[],[],Fd}, Ps), iformat(Fd, "Total", "", "", io_lib:write(Reds), io_lib:write(Msgs), io_lib:write(Heap), io_lib:write(Stack)), lists:foreach(fun(Susp) -> display_susp1(Fd, Susp) end, Susp1), lists:foreach(fun(Susp) -> display_susp2(Fd, Susp) end, Susp2), lists:foreach(fun(Susp) -> display_susp3(Fd, Susp) end, MemSusp). palive(Pid) -> case process_info(Pid, status) of undefined -> false; {status, exiting} -> false; _ -> true end. pzombie(Pid) -> case process_info(Pid, status) of undefined -> false; {status, exiting} -> true; _ -> false end. -define(MEM_LARGE, 40000). display_info(Pid, {R,M,H,St,S1,S2,S3,Fd}) -> case process_info(Pid) of undefined -> {R, M}; Info -> Call = initial_call(Info), Curr = fetch(current_function, Info), Reds = fetch(reductions, Info), LM = fetch(message_queue_len, Info), Heap = fetch(heap_size, Info), Stack = fetch(stack_size, Info), Mem = case process_info(Pid, memory) of undefined -> 0; {memory, Int} -> Int end, iformat(Fd, io_lib:write(Pid), mfa_string(Call), mfa_string(Curr), io_lib:write(Reds), io_lib:write(LM), io_lib:write(Heap), io_lib:write(Stack)), %% if it got msgs, it's suspicios NS1 = if LM > 0 -> [{Pid, Reds, LM} | S1]; true -> S1 end, %% if it's in gen:wait_resp* it's suspicios NS2 = case Curr of {gen, wait_resp, _} -> [{Pid, Reds} | S2]; {gen, wait_resp_mon, _} -> [{Pid, Reds} | S2]; _ -> S2 end, %% If it is large .. it is suspicios NS3 = if Mem > ?MEM_LARGE -> [{Pid, Mem} | S3]; true -> S3 end, {R+Reds, M+LM, H+Heap,St+Stack, NS1, NS2, NS3, Fd} end. display_susp1(Fd, {Pid, Reds0, LM0}) -> case process_info(Pid) of undefined -> ok; Info -> Reds1 = fetch(reductions, Info), LM1 = fetch(message_queue_len, Info), Msgs = fetch(messages, Info), Bt = case process_info(Pid, backtrace) of {backtrace, Bin} -> binary_to_list(Bin); _ -> [] end, if LM1 > 0 -> %% still suspicious sock_format(Fd, "*** Suspicious *** : ~-12w, Qlen = ~4w/~-4w, " "Reds = ~12w/~-12w\n", [Pid, LM0, LM1, Reds0, Reds1]), lists:foreach( fun(Msg) -> sock_format(Fd, " ~p\n",[Msg]) end, Msgs), gen_sep(Fd), sock_format(Fd, "\n\n\n\n*** Backtrace *** for ~w\n~s\n", [Pid,Bt]); true -> ok end end. display_susp2(Fd, {Pid, Reds0}) -> case process_info(Pid, reductions) of undefined -> ok; {reductions, Reds0} -> %% it hasn't done any work... print bt case process_info(Pid, backtrace) of {backtrace, Bin} -> gen_sep(Fd), sock_format(Fd, "\n\n\n\n*** Backtrace (gen_wait) " "*** for ~w\n~s\n", [Pid, binary_to_list(Bin)]); _ -> ok end; _ -> ok end. display_susp3(Fd, {Pid, _Mem}) -> case {process_info(Pid, memory), process_info(Pid, current_function)} of {undefined, _} -> ok; {_, {current_function,{yaws_debug,display_susp3,2}}} -> ok; {{memory, Mem2}, _} when Mem2 > ?MEM_LARGE -> %% it's still too big case process_info(Pid, backtrace) of {backtrace, Bin} -> gen_sep(Fd), sock_format(Fd, "\n\n\n\n*** Backtrace (mem=~p) " "*** for ~w\n~p~n~s\n", [Mem2, Pid, process_info(Pid), binary_to_list(Bin)]); _ -> ok end; _ -> ok end. initial_call(Info) -> case fetch(initial_call, Info) of {proc_lib, init_p, 5} -> proc_lib:translate_initial_call(Info); ICall -> ICall end. mfa_string({M, F, A}) -> io_lib:format("~w:~w/~w", [M, F, A]); mfa_string(X) -> io_lib:write(X). fetch(Key, Info) -> case lists:keysearch(Key, 1, Info) of {value, {_, Val}} -> Val; false -> 0 end. iformat(Fd, A1, A2, A3, A4, A5, A6, A7) -> sock_format(Fd, "~-12s ~-23s ~-23s ~12s ~4s ~12s ~10s\n", [A1,A2,A3,A4,A5,A6,A7]). sock_format(Sock, Fmt, Args) -> gen_tcp:send(Sock, io_lib:format(Fmt, Args)). -define(COLLECT_TIMEOUT, 10000). %% purpose of this collect function is to not hang, remember a probable %% reason for running debug-dump is that the system is in a %% corrupt state. collect(F, Sock, User) -> SELF = self(), Pid = spawn(fun() -> F(Sock), SELF ! {self(), ok}, timer:sleep(infinity) end), Ref = erlang:monitor(process, Pid), receive {Pid, ok} -> erlang:demonitor(Ref), exit(Pid, shutdown), ok; Down = {'DOWN', Ref, _,_,_} -> sock_format(Sock, "*** Failed to collect ~s: ~p~n", [User, Down]), ok after ?COLLECT_TIMEOUT -> erlang:demonitor(Ref), sock_format(Sock, "*** Failed to collect ~s: timeout~n", [User]), {pid, Pid} % Let it hang for proc status, exit after end. send_status(Sock) -> {InitStatus, _} = init:get_status(), sock_format(Sock, "vsn: ~s\n", [yaws_generated:version()]), sock_format(Sock, "status: ~p\n", [InitStatus]), ok. send_inet(Sock) -> Chars = capture_io(fun() -> inet:i() end), sock_format(Sock, "inet:i() output ~n~s~n", [Chars]), ok. %% This function runs a Fun that is producing IO through %% io:format() and collects the IO and retuns the IO as a char list %% Returns io_list() | {timeout, io_list()} %% capture_io(Fun) -> do_capture_io(Fun). %% capture_io(Fun, MilliSecTimeout) -> %% {ok, Tref} = timer:send_after(MilliSecTimeout, capio_timeout), %% Chars = do_capture_io(Fun), %% timer:cancel(Tref), %% Chars. do_capture_io(Fun) -> Pid = spawn(fun() -> receive run -> ok end, Fun() end), Mref = erlang:monitor(process,Pid), group_leader(self(), Pid), Pid ! run, collect_io(Pid, Mref, []). collect_io(Pid, Mref, Ack) -> receive {'DOWN', Mref, _,_,_} -> Ack; {io_request, From, Me, {put_chars, M, F, A}} -> From ! {io_reply, Me, ok}, collect_io(Pid, Mref, [Ack, apply(M,F, A)]); {io_request, From, Me, {put_chars, unicode, M, F, A}} -> From ! {io_reply, Me, ok}, collect_io(Pid, Mref, [Ack, apply(M,F, A)]); capio_timeout -> {timeout, Ack} end. yaws-2.0.2/src/yaws_generated.template0000664000175000017500000000104312605311412014737 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_generated.template %%% Author : Klacke %%% Purpose : %%% Created : 10 Jun 2002 by Klacke %%%---------------------------------------------------------------------- %% generated code from some environment variables -module(yaws_generated). -author('klacke@bluetail.com'). -export([version/0, vardir/0, etcdir/0]). version() -> "%VSN%". vardir() -> "%VARDIR%". etcdir() -> "%ETCDIR%". yaws-2.0.2/src/yaws_soap12_lib.erl0000664000175000017500000010771212605311412013715 00000000000000%%%------------------------------------------------------------------- %%% Created : 29 Nov 2006 by Torbjorn Tornkvist %%% Author : Willem de Jong (w.a.de.jong@gmail.com). %%% Desc. : Common SOAP code. %%%------------------------------------------------------------------- %%% modified (WdJ, May 2007): deal with imports in the WSDL. %%% modified (WdJ, August 2007): the WSDL can contain more than 1 schema %%% copied from yaws_soap_lib (Kaloyan Dimitrov, February 2012): %% to be used for soap12 calls -module(yaws_soap12_lib). -export([initModel/1, initModel/2, initModelFile/1, config_file_xsd/0, call/3, call/4, call/5, call/6, call/8, call_attach/4, call_attach/5, call_attach/8, write_hrl/2, write_hrl/3, findHeader/2, parseMessage/2, makeFault/2, is_wsdl/1, wsdl_model/1, wsdl_op_service/1, wsdl_op_port/1, wsdl_op_operation/1, wsdl_op_binding/1, wsdl_op_address/1, wsdl_op_action/1, wsdl_operations/1, get_operation/2 ]). %%% For testing... -export([qtest/0]). -include("../include/yaws_soap.hrl"). -include("../include/soap-envelope.hrl"). -include("../include/wsdl11soap12.hrl"). -define(HTTP_REQ_TIMEOUT, 20000). %%-define(dbg(X,Y), %% error_logger:info_msg("*dbg ~p(~p): " X, %% [?MODULE, ?LINE | Y])). -define(dbg(X,Y), true). -record(yaws_soap_config, {atts, xsd_path, user_module, wsdl_file, add_files}). -record(xsd_file, {atts, name, prefix, import_specs}). -record(import_specs, {atts, namespace, prefix, location}). -record(namespace_spec, {namespace, prefix}). -record(namespace_registry, {specs = [], counter = 0}). -define(DefaultPrefix, "p"). -define(CustomPrefix, "cp"). %%% %%% Writes the header file (record definitions) for a WSDL file %%% write_hrl(WsdlURL, Output) when is_list(WsdlURL) -> write_hrl(initModel(WsdlURL), Output); write_hrl(#wsdl{model = Model}, Output) when is_list(Output) -> erlsom:write_hrl(Model, Output). write_hrl(WsdlURL, Output, PrefixOrOptions) when is_list(WsdlURL),is_list(PrefixOrOptions) -> write_hrl(initModel(WsdlURL, PrefixOrOptions), Output). %%% For testing only... qtest() -> call("http://www.webservicex.net/WeatherForecast.asmx?WSDL", "GetWeatherByPlaceName", ["Boston"]). %%% -------------------------------------------------------------------- %%% Access functions %%% -------------------------------------------------------------------- is_wsdl(Wsdl) when is_record(Wsdl,wsdl) -> true; is_wsdl(_) -> false. wsdl_operations(#wsdl{operations = Ops}) -> Ops. wsdl_model(#wsdl{model = Model}) -> Model. wsdl_op_service(#operation{service = Service}) -> Service. wsdl_op_port(#operation{port = Port}) -> Port. wsdl_op_operation(#operation{operation = Op}) -> Op. wsdl_op_binding(#operation{binding = Binding}) -> Binding. wsdl_op_address(#operation{address = Address}) -> Address. wsdl_op_action(#operation{action = Action}) -> Action. %%% -------------------------------------------------------------------- %%% For Quick deployment %%% -------------------------------------------------------------------- call(WsdlURL, Operation, ListOfData) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, ?DefaultPrefix), call(Wsdl, Operation, ListOfData); call(Wsdl, Operation, ListOfData) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> Msg = mk_msg(?DefaultPrefix, Operation, ListOfData), call(Wsdl, Operation, Op#operation.port, Op#operation.service, [], Msg); Else -> Else end. %%% -------------------------------------------------------------------- %%% Takes http headers %%% -------------------------------------------------------------------- call(WsdlURL, Operation, ListOfData, http_headers, HttpHeaders) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, ?DefaultPrefix), call(Wsdl, Operation, ListOfData, http_headers, HttpHeaders); call(Wsdl, Operation, ListOfData, http_headers, HttpHeaders) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> Msg = mk_msg(?DefaultPrefix, Operation, ListOfData), call(Wsdl, Operation, Op#operation.port, Op#operation.service, [], Msg, http_headers, HttpHeaders); Else -> Else end; %%% -------------------------------------------------------------------- %%% With additional specified prefix %%% -------------------------------------------------------------------- call(WsdlURL, Operation, ListOfData, prefix, Prefix) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, Prefix), call(Wsdl, Operation, ListOfData, prefix, Prefix ); call(Wsdl, Operation, ListOfData, prefix, Prefix) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> Msg = mk_msg(Prefix, Operation, ListOfData), call(Wsdl, Operation, Op#operation.port, Op#operation.service, [], Msg); Else -> Else end. %%% -------------------------------------------------------------------- %%% Takes the actual records for the Header and Body message. %%% -------------------------------------------------------------------- call(WsdlURL, Operation, Header, Msg) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, ?DefaultPrefix), call(Wsdl, Operation, Header, Msg); call(Wsdl, Operation, Header, Msg) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> call(Wsdl, Operation, Op#operation.port, Op#operation.service, Header, Msg); Else -> Else end. mk_msg(_Prefix, _Operation, ListOfData) -> ListOfData. % rest of record data get_operation([#operation{operation = X} = Op|_], X) -> {ok, Op}; get_operation([_|T], Op) -> get_operation(T, Op); get_operation([], _Op) -> {error, "operation not found"}. %%% -------------------------------------------------------------------- %%% Make a SOAP request (no attachments) %%% -------------------------------------------------------------------- call(Wsdl, Operation, Port, Service, Headers, Message) -> call_attach(Wsdl, Operation, Port, Service, Headers, Message, [], []). %%% -------------------------------------------------------------------- %%% Make a SOAP request (with http artifacts) %%% -------------------------------------------------------------------- call(Wsdl, Operation, Port, Service, Headers, Message, http_headers, HttpHeaders) -> call_attach(Wsdl, Operation, Port, Service, Headers, Message, [], HttpHeaders); call(Wsdl, Operation, Port, Service, Headers, Message, http_details, HttpDetails) -> call_attach(Wsdl, Operation, Port, Service, Headers, Message, [], http_details, HttpDetails). %%% -------------------------------------------------------------------- %%% For Quick deployment (with attachments) %%% -------------------------------------------------------------------- call_attach(WsdlURL, Operation, ListOfData, Attachments) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, ?DefaultPrefix), call_attach(Wsdl, Operation, ListOfData, Attachments); call_attach(Wsdl, Operation, ListOfData, Attachments) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> Msg = mk_msg(?DefaultPrefix, Operation, ListOfData), call_attach(Wsdl, Operation, Op#operation.port, Op#operation.service, [], Msg, Attachments, []); Else -> Else end. %%% -------------------------------------------------------------------- %%% Takes the actual records for the Header and Body message %%% (with attachments) %%% -------------------------------------------------------------------- call_attach(WsdlURL, Operation, Header, Msg, Attachments) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, ?DefaultPrefix), call_attach(Wsdl, Operation, Header, Msg, Attachments); call_attach(Wsdl, Operation, Header, Msg, Attachments) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> call_attach(Wsdl, Operation, Op#operation.port, Op#operation.service, Header, Msg, Attachments, []); Else -> Else end. %%% -------------------------------------------------------------------- %%% Make a SOAP request (with attachments) %%% -------------------------------------------------------------------- call_attach(Wsdl, Operation, Port, Service, Headers, Message, Attachments, HttpHeaders) -> call_attach(Wsdl, Operation, Port, Service, Headers, Message, Attachments, http_details, [{headers, HttpHeaders}]). call_attach(#wsdl{operations = Operations, model = Model}, Operation, Port, Service, Headers, Message, Attachments, http_details, HttpDetails) -> HttpHeaders = findListValue(headers, HttpDetails), HttpClientOptions = findListValue(client_options, HttpDetails), %% find the operation case findOperation(Operation, Port, Service, Operations) of #operation{address = URL, action=Action, operation = Operation} -> %% Add the Soap envelope Envelope = mk_envelope(Message, Headers), %% Encode the message case erlsom:write(Envelope, Model) of {ok, XmlMessage} -> {ContentType, Request} = make_request_body(XmlMessage, Attachments, Action), ?dbg("+++ Request = ~p~n", [Request]), HttpRes = http_request(URL, Action, Request, HttpClientOptions, HttpHeaders, ContentType), ?dbg("+++ HttpRes = ~p~n", [HttpRes]), case HttpRes of {ok, _Code, _ReturnHeaders, Body} -> parseMessage(Body, Model); Error -> %% in case of HTTP error: return %% {error, description} Error end; {error, EncodingError} -> {error, {encoding_error, EncodingError}} end; false -> {error, {unknown_operation, Operation}} end. findListValue(Key, KeyVals) -> case lists:keyfind(Key, 1, KeyVals) of {Key, List} -> List; false -> [] end. %%% %%% returns {ok, Header, Body} | {error, Error} %%% parseMessage(Message, #wsdl{model = Model}) -> parseMessage(Message, Model); %% parseMessage(Message, Model) -> Parsed = erlsom:scan(Message, Model), case Parsed of {ok, #'soap:Envelope'{'Body' = #'soap:Body'{choice = Body}, 'Header' = undefined}, _} -> {ok, undefined, Body}; {ok, #'soap:Envelope'{'Body' = #'soap:Body'{choice = Body}, 'Header' = #'soap:Header'{choice = Header}}, _} -> {ok, Header, Body}; {error, ErrorMessage} -> {error, {decoding, ErrorMessage}} end. findOperation(_Operation, _Port, _Service, []) -> false; findOperation(Operation, Port, Service, [Op = #operation{operation = Operation, port = Port, service = Service} | _]) -> Op; findOperation(Operation, Port, Service, [#operation{} | Tail]) -> findOperation(Operation, Port, Service, Tail). mk_envelope(M, H) when is_tuple(M) -> mk_envelope([M], H); mk_envelope(M, H) when is_tuple(H) -> mk_envelope(M, [H]); %% mk_envelope(Messages, []) when is_list(Messages) -> #'soap:Envelope'{'Body' = #'soap:Body'{choice = Messages}}; mk_envelope(Messages, Headers) when is_list(Messages),is_list(Headers) -> #'soap:Envelope'{'Body' = #'soap:Body'{choice = Messages}, 'Header' = #'soap:Header'{choice = Headers}}. %%% -------------------------------------------------------------------- %%% Parse a WSDL file and return a 'Model' %%% -------------------------------------------------------------------- initModel(WsdlFile) -> initModel(WsdlFile, ?DefaultPrefix). %% PrefixOrOptions can be a property list that contains the options %% for Erlsom, or a String. If it is a string, this is used as the %% Erlsom 'prefix' option (and the other options are left unspecified). initModel(WsdlFile, PrefixOrOptions) -> Options = case is_string(PrefixOrOptions) of no -> %% It is an option list %% Add the default prefix at the end - it will only be used %% if no other prefix is specified PrefixOrOptions ++ [{prefix, ?DefaultPrefix}]; _ -> %% just the prefix [{prefix, PrefixOrOptions}] end, PrivDir = priv_dir(), initModel2(WsdlFile, Options, PrivDir, undefined, undefined). initModelFile(ConfigFile) -> {ok, ConfigSchema} = erlsom:compile_xsd(config_file_xsd()), %% read (parse) the config file {ok, Config, _} = erlsom:scan_file(ConfigFile, ConfigSchema), #yaws_soap_config{xsd_path = XsdPath, wsdl_file = Wsdl, add_files = AddFiles} = Config, #xsd_file{name = WsdlFile, prefix = Prefix, import_specs = Import} = Wsdl, initModel2(WsdlFile, [{prefix, Prefix}], XsdPath, Import, AddFiles). priv_dir() -> yaws:get_priv_dir(). initModel2(WsdlFile, ErlsomOptions, Path, Import, AddFiles) -> WsdlName = filename:join([Path, "wsdl.xsd"]), IncludeWsdl = {"http://schemas.xmlsoap.org/wsdl/", "wsdl", WsdlName}, {ok, WsdlModel} = erlsom:compile_xsd_file( filename:join([Path, "wsdl11soap12.xsd"]), [{prefix, "soap"}, {include_files, [IncludeWsdl]}]), %% uncomment to generate the wsdl11soap12.hrl file %% erlsom:write_hrl(WsdlModel, "/home/kalski/test/wsdl11soap12.hrl"), %% add the xsd model (since xsd is also used in the wsdl) WsdlModel2 = erlsom:add_xsd_model(WsdlModel), Options = ErlsomOptions ++ makeOptions(Import), %% parse Wsdl {Model, Operations} = parseWsdls([WsdlFile], WsdlModel2, Options, {undefined, []}), %% TODO: add files as required %% now compile envelope.xsd, and add Model {ok, EnvelopeModel} = erlsom:compile_xsd_file( filename:join([Path, "soap-envelope.xsd"]), [{prefix, "soap"}, {include_files, [{"http://www.w3.org/XML/1998/namespace", undefined, filename:join([Path, "xml.xsd"])}]}]), SoapModel = erlsom:add_model(EnvelopeModel, Model), %% uncomment to generate the soap-envelope.hrl file %% erlsom:write_hrl(EnvelopeModel, "/home/kalski/test/soap-envelope.hrl"), SoapModel2 = addModels(AddFiles, SoapModel), #wsdl{operations = Operations, model = SoapModel2}. %%% -------------------------------------------------------------------- %%% Parse a list of WSDLs and import (recursively) %%% Returns {Model, Operations} %%% -------------------------------------------------------------------- parseWsdls(WsdlFiles, WsdlModel, Options, Acc) -> parseWsdls(WsdlFiles, WsdlModel, Options, Acc, #namespace_registry{}). parseWsdls([], _WsdlModel, _Options, Acc, _NSRegistry) -> Acc; parseWsdls([WsdlFile | Tail], WsdlModel, Options, {AccModel, AccOperations}, NSRegistry) -> WsdlFileNoSpaces = rmsp(WsdlFile), {ok, WsdlFileContent} = get_url_file(WsdlFileNoSpaces), {ok, ParsedWsdl, _} = erlsom:scan(WsdlFileContent, WsdlModel), WsdlTargetNameSpace = getTargetNamespaceFromWsdl(ParsedWsdl), {Prefix, PrefixlessOptions} = remove_prefix_option(Options), TNSEnrichedNSRegistry = extend_namespace_registry(WsdlTargetNameSpace, Prefix, NSRegistry), %% get the xsd elements from this model, and hand it over to erlsom_compile. Xsds = getXsdsFromWsdl(ParsedWsdl), %% Now we need to build a list: [{Namespace, Xsd, Prefix}, ...] for %% all the Xsds in the WSDL. %% This list is used when a schema includes one of the other schemas. %% The AXIS java2wsdl tool generates wsdls that depend on this feature. {ImportsEnrichedNSRegistry, ImportList} = makeImportList( Xsds, TNSEnrichedNSRegistry, []), Model2 = addSchemas(Xsds, AccModel, PrefixlessOptions, ImportList), Ports = getPorts(ParsedWsdl), Operations = getOperations(ParsedWsdl, Ports), Imports = getImports(filename:dirname(WsdlFileNoSpaces), ParsedWsdl), %% use Options rather than PrefixlessOptions because imports come in %% the wsdl targetNamespace Model3 = addSchemaFiles(Imports, Model2, Options, []), Acc2 = {Model3, Operations ++ AccOperations}, %% process imports (recursively, so that imports in the imported files are %% processed as well). %% For the moment, the namespace is ignored on operations etc. %% this makes it a bit easier to deal with imported wsdl's. %% TODO uncomment if imports can be WSDL %%Acc3 = parseWsdls(Imports, WsdlModel, Options, Acc2, %% ImportsEnrichedNSRegistry), parseWsdls(Tail, WsdlModel, PrefixlessOptions, Acc2, ImportsEnrichedNSRegistry). remove_prefix_option(Options) -> case lists:keytake(prefix, 1, Options) of {value, {prefix, Prefix}, NewOptions} -> {Prefix, NewOptions}; false -> {undefined, Options} end. %empty registry, initializing extend_namespace_registry(WsdlTargetNameSpace, undefined, #namespace_registry{specs = []} = NSRegistry) -> {NewCounter, NewPrefix} = create_unique_prefix(NSRegistry), NSRegistry#namespace_registry{ specs = [#namespace_spec{namespace = WsdlTargetNameSpace, prefix = NewPrefix}], counter = NewCounter}; extend_namespace_registry(WsdlTargetNameSpace, Prefix, #namespace_registry{specs = []} = NSRegistry) -> NSRegistry#namespace_registry{ specs = [#namespace_spec{namespace = WsdlTargetNameSpace, prefix = Prefix}]}; extend_namespace_registry(WsdlTargetNameSpace, _Prefix, #namespace_registry{specs = Specs} = NSRegistry) -> case lists:keyfind(WsdlTargetNameSpace, #namespace_spec.namespace, Specs) of #namespace_spec{} -> NSRegistry; false -> {NewCounter, NewPrefix} = create_unique_prefix(NSRegistry), NSRegistry#namespace_registry{ specs = [#namespace_spec{namespace = WsdlTargetNameSpace, prefix = NewPrefix}|Specs], counter = NewCounter} end. create_unique_prefix(#namespace_registry{specs = Specs, counter = Counter} = NSRegistry) -> NewCounter = Counter+1, NewPrefix = ?CustomPrefix ++ integer_to_list(NewCounter), case lists:keyfind(NewPrefix, #namespace_spec.prefix, Specs) of #namespace_spec{} -> create_unique_prefix(NSRegistry#namespace_registry{ counter = Counter+1}); false -> {NewCounter, NewPrefix} end. %%% -------------------------------------------------------------------- %%% build a list: [{Namespace, Xsd}, ...] for all the Xsds in the WSDL. %%% This list is used when a schema inlcudes one of the other schemas. %%% The AXIS java2wsdl tool generates wsdls that depend on this feature. makeImportList([], NSRegistry, Acc) -> {NSRegistry, Acc}; makeImportList([ Xsd | Tail], NSRegistry, Acc) -> XsdNS = erlsom_lib:getTargetNamespaceFromXsd(Xsd), NewNSRegistry = extend_namespace_registry(XsdNS, undefined, NSRegistry), #namespace_spec{prefix = Prefix} = lists:keyfind(XsdNS, #namespace_spec.namespace, NewNSRegistry#namespace_registry.specs), makeImportList(Tail, NewNSRegistry, [{XsdNS, Prefix, Xsd} | Acc]). getTargetNamespaceFromWsdl(#'wsdl:tDefinitions'{targetNamespace = TNS}) -> TNS. %%% -------------------------------------------------------------------- %%% compile each of the schemas, and add it to the model. %%% Returns Model %%% (TODO: using the same prefix for all XSDS makes no sense) %%% -------------------------------------------------------------------- addSchemas([], AccModel, _PrefixlessOptions, _ImportList) -> AccModel; addSchemas([Xsd| Tail], AccModel, PrefixlessOptions, ImportList) -> Model2 = case Xsd of undefined -> AccModel; _ -> {_, Prefix, _} = lists:keyfind( erlsom_lib:getTargetNamespaceFromXsd(Xsd), 1, ImportList), NewOptions = [{prefix, Prefix}|PrefixlessOptions], {ok, Model} = erlsom_compile:compile_parsed_xsd( Xsd, [{include_files, ImportList} |NewOptions]), case AccModel of undefined -> Model; _ -> erlsom:add_model(AccModel, Model) end end, addSchemas(Tail, Model2, PrefixlessOptions, ImportList). %%% -------------------------------------------------------------------- %%% compile each of the schema files, and add it to the model. %%% Returns Model %%% (TODO: using the same prefix for all XSD files makes no sense) %%% -------------------------------------------------------------------- addSchemaFiles([], AccModel, _Options, _ImportList) -> AccModel; addSchemaFiles([Xsd| Tail], AccModel, Options, ImportList) -> {ok, Model} = erlsom:compile_xsd_file(get_file_with_path(Xsd), [{include_files, ImportList} |Options]), Model2 = case AccModel of undefined -> Model; _ -> erlsom:add_model(AccModel, Model) end, addSchemaFiles(Tail, Model2, Options, ImportList). %%% -------------------------------------------------------------------- %%% Get a file from an URL spec. %%% -------------------------------------------------------------------- get_url_file("http://"++_ = URL) -> case httpc:request(URL) of {ok,{{_HTTP,200,_OK}, _Headers, Body}} -> {ok, Body}; {ok,{{_HTTP,RC,Emsg}, _Headers, _Body}} -> error_logger:error_msg("~p: http-request got: ~p~n", [?MODULE, {RC, Emsg}]), {error, "failed to retrieve: "++URL}; {error, Reason} -> error_logger:error_msg("~p: http-request failed: ~p~n", [?MODULE, Reason]), {error, "failed to retrieve: "++URL} end; get_url_file("file://"++Fname) -> {ok, Bin} = file:read_file(Fname), {ok, binary_to_list(Bin)}; %% added this, since this is what is used in many WSDLs (i.e.: just a filename). get_url_file(Fname) -> {ok, Bin} = file:read_file(Fname), {ok, binary_to_list(Bin)}. %%% -------------------------------------------------------------------- %%% Make a HTTP Request %%% -------------------------------------------------------------------- http_request(URL, Action, Request, Options, Headers, ContentType) -> case code:ensure_loaded(ibrowse) of {module, ibrowse} -> %% If ibrowse exist in the path then let's use it... ibrowse_request(URL, Action, Request, Options, Headers, ContentType); _ -> %% ...otherwise, let's use the OTP http client. inets_request(URL, Action, Request, Options, Headers, ContentType) end. inets_request(URL, Action, Request, Options, Headers, ContentType) -> case Action of undefined -> NHeaders = Headers; _ -> NHeaders = [{"SOAPAction", Action} | Headers] end, NewHeaders = case proplists:get_value("Host", NHeaders) of undefined -> [{"Host", "localhost:8800"}|NHeaders]; _ -> NHeaders end, NewOptions = [{cookies, enabled}|Options], httpc:set_options(NewOptions), case httpc:request(post, {URL,NewHeaders, ContentType, Request}, [{timeout,?HTTP_REQ_TIMEOUT}], [{sync, true}, {full_result, true}, {body_format, string}]) of {ok,{{_HTTP,200,_OK},ResponseHeaders,ResponseBody}} -> {ok, 200, ResponseHeaders, ResponseBody}; {ok,{{_HTTP,500,_Descr},ResponseHeaders,ResponseBody}} -> {ok, 500, ResponseHeaders, ResponseBody}; {ok,{{_HTTP,ErrorCode,_Descr},ResponseHeaders,ResponseBody}} -> {ok, ErrorCode, ResponseHeaders, ResponseBody}; Other -> Other end. ibrowse_request(URL, Action, Request, Options, Headers, ContentType) -> case start_ibrowse() of ok -> NewHeaders = [{"Content-Type", ContentType} | case Action of undefined -> Headers; _ -> [{"SOAPAction", Action} | Headers] end], IbrowseF = case lists:keyfind(ibrowse_timeout, 1, Options) of {_, Timeout} -> fun() -> ibrowse:send_req(URL, NewHeaders, post, Request, Options, Timeout) end; false -> fun() -> ibrowse:send_req(URL, NewHeaders, post, Request, Options) end end, case IbrowseF() of {ok, Status, ResponseHeaders, ResponseBody} -> {ok, list_to_integer(Status), ResponseHeaders, ResponseBody}; {error, Reason} -> {error, Reason} end; error -> {error, "could not start ibrowse"} end. start_ibrowse() -> case ibrowse:start() of {ok, _} -> ok; {error, {already_started, _}} -> ok; _ -> error end. rmsp(Str) -> string:strip(Str, left). make_request_body(Content, [], Operation) -> {"application/soap+xml;charset=UTF-8;action=\"" ++ Operation ++ "\"", ""++ Content}; make_request_body(Content, AttachedFiles, _Operation) -> {"application/dime", yaws_dime:encode("" ++ Content, AttachedFiles)}. makeFault(FaultCode, FaultString) -> try "" "" "" "SOAP-ENV:" ++ FaultCode ++ "" ++ "" ++ FaultString ++ "" ++ "" "" "" catch _:_ -> "" "" "" "SOAP-ENV:Server" "Server error" "" "" "" end. %% record http_header is not defined?? findHeader(Label, Headers) -> findHeader0(yaws:to_lower(Label), Headers). findHeader0(_Label, []) -> undefined; findHeader0(Label, [{_,_,Hdr,_,Val}|T]) -> case {Label, yaws:to_lower(Hdr)} of {X,X} -> Val; _ -> findHeader0(Label, T) end; findHeader0(_Label, undefined) -> undefined. makeOptions(undefined) -> []; makeOptions(Import) -> lists:map(fun makeOption/1, Import). %% -record(import_specs, {atts, namespace, prefix, location}). makeOption(#import_specs{namespace = Ns, prefix = Pf, location = Lc}) -> {Ns, Pf, Lc}. addModels(undefined, Model) -> Model; addModels(Import, Model) -> lists:foldl(fun addModel/2, Model, Import). %% -record(xsd_file, {atts, name, prefix, import_specs}). addModel(undefined, Acc) -> Acc; addModel(#xsd_file{name = XsdFile, prefix = Prefix, import_specs = Import}, Acc) -> Options = makeOptions(Import), {ok, Model2} = erlsom:add_xsd_file(XsdFile, [{prefix, Prefix}|Options],Acc), Model2. %% returns [#port{}] %% -record(port, {service, port, binding, address}). getPorts(ParsedWsdl) -> Services = getTopLevelElements(ParsedWsdl, 'wsdl:tService'), getPortsFromServices(Services, []). getPortsFromServices([], Acc) -> Acc; getPortsFromServices([Service|Tail], Acc) -> getPortsFromServices(Tail, getPortsFromService(Service) ++ Acc). getPortsFromService(#'wsdl:tService'{name = Name, port = Ports}) -> getPortsInfo(Ports, Name, []). getPortsInfo([], _Name, Acc) -> Acc; getPortsInfo([#'wsdl:tPort'{name = Name, binding = Binding, choice = [#'soap:tAddress'{location = URL}]} | Tail], ServiceName, Acc) -> getPortsInfo(Tail, ServiceName, [#port{service = ServiceName, port = Name, binding = Binding, address = URL}|Acc]); %% non-soap bindings are ignored. getPortsInfo([#'wsdl:tPort'{} | Tail], ServiceName, Acc) -> getPortsInfo(Tail, ServiceName, Acc). getTopLevelElements(#'wsdl:tDefinitions'{choice1 = TLElements}, Type) -> getTopLevelElements(TLElements, Type, []). getTopLevelElements([], _Type, Acc) -> Acc; getTopLevelElements([#'wsdl:anyTopLevelOptionalElement'{choice = Tuple}| Tail], Type, Acc) -> case element(1, Tuple) of Type -> getTopLevelElements(Tail, Type, [Tuple|Acc]); _ -> getTopLevelElements(Tail, Type, Acc) end. get_file_with_path(Url) -> case Url of "http://" ++ _ -> undefined; "file://" ++ FName -> FName; _ -> Url end. getImports(WsdlDirname, Definitions) -> Imports = getTopLevelElements(Definitions, 'wsdl:tImport'), lists:map(fun(Import) -> case WsdlDirname of "http://" ++ _AbsDirname -> WsdlDirname ++ "/" ++ Import#'wsdl:tImport'.location; "file://" ++ _AbsDirname -> WsdlDirname ++ "/" ++ Import#'wsdl:tImport'.location; Fname -> filename:join(Fname, Import#'wsdl:tImport'.location) end end, Imports). %% returns [#operation{}] getOperations(ParsedWsdl, Ports) -> Bindings = getTopLevelElements(ParsedWsdl, 'wsdl:tBinding'), getOperationsFromBindings(Bindings, Ports, []). getOperationsFromBindings([], _Ports, Acc) -> Acc; getOperationsFromBindings([Binding|Tail], Ports, Acc) -> getOperationsFromBindings(Tail, Ports, getOperationsFromBinding(Binding, Ports) ++ Acc). getOperationsFromBinding(#'wsdl:tBinding'{name = BindingName, type = BindingType, choice = _Choice, operation = Operations}, Ports) -> %% TODO: get soap info from Choice getOperationsFromOperations(Operations, BindingName, BindingType, Operations, Ports, []). getOperationsFromOperation(BindingName, BindingType, Ports, Name, Action, Operations, Tail, Acc) -> %% lookup Binding in Ports, and create a combined result Ports2 = searchPorts(BindingName, Ports), %% for each port, make an operation record CombinedPorts = combinePorts(Ports2, Name, BindingName, Action), getOperationsFromOperations( Tail, BindingName, BindingType, Operations, Ports, CombinedPorts ++ Acc). getOperationsFromOperations([], _BindingName, _BindingType, _Operations, _Ports, Acc) -> Acc; getOperationsFromOperations([#'wsdl:tBindingOperation'{name = Name, choice = Choice} | Tail], BindingName, BindingType, Operations, Ports, Acc) -> %% get SOAP action from Choice, case Choice of [#'soap:tOperation'{soapAction = Action}] -> getOperationsFromOperation(BindingName, BindingType, Ports, Name, Action, Operations, Tail, Acc); _ -> getOperationsFromOperation(BindingName, BindingType, Ports, Name, undefined, Operations, Tail, Acc) end. combinePorts(Ports, Name, BindingName, Action) -> combinePorts(Ports, Name, BindingName, Action, []). combinePorts([], _Name, _BindingName, _Action, Acc) -> Acc; combinePorts([#port{service = Service, port = PortName, address = Address} | Tail], Name, BindingName, Action, Acc) -> combinePorts(Tail, Name, BindingName, Action, [#operation{service = Service, port = PortName, operation = Name, binding = BindingName, address = Address, action = Action} | Acc]). searchPorts(BindingName, Ports) -> searchPorts(BindingName, Ports, []). searchPorts(_BindingName, [], Acc) -> Acc; searchPorts(BindingName, [Port | Tail], Acc) -> PortBinding = erlsom_lib:localName(Port#port.binding), case PortBinding of BindingName -> searchPorts(BindingName, Tail, [Port | Acc]); _ -> searchPorts(BindingName, Tail, Acc) end. %% copied from yaws/json.erl is_string([]) -> yes; is_string(List) -> is_string(List, non_unicode). is_string([C|Rest], non_unicode) when C >= 0, C =< 255 -> is_string(Rest, non_unicode); is_string([C|Rest], _) when C =< 65000 -> is_string(Rest, unicode); is_string([], non_unicode) -> yes; is_string([], unicode) -> unicode; is_string(_, _) -> no. getXsdsFromWsdl(Definitions) -> case getTopLevelElements(Definitions, 'wsdl:tTypes') of [#'wsdl:tTypes'{choice = Xsds}] -> Xsds; [] -> [] end. config_file_xsd() -> "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "". yaws-2.0.2/src/yaws_zlib.erl0000664000175000017500000000625212605311412012717 00000000000000%%% Utility functions for zlib. -module(yaws_zlib). -author('carsten@codimi.de'). -include("../include/yaws.hrl"). -export([gzipInit/1, gzipInit/2, gzipEnd/1, gzipDeflate/4, gzip/1, gzip/2]). gzipInit(Z) -> gzipInit(Z, #deflate{}). gzipInit(Z, DOpts) -> ok = zlib:deflateInit(Z, DOpts#deflate.compression_level, deflated, DOpts#deflate.window_size, DOpts#deflate.mem_level, DOpts#deflate.strategy), undefined. gzipEnd(Z) -> zlib:deflateEnd(Z). gzipDeflate(Z, undefined, Bin, Flush) -> Crc32 = zlib:crc32(Z), Head = << % ID 16#1f, 16#8b, % deflate 8:8, % flags 0:8, % mtime 0:32, % xflags 0:8, % OS_UNKNOWN % Set to Unix instead? 255:8>>, {ok, Priv, Bs} = gzipDeflate(Z, {Crc32,0}, Bin, Flush), {ok, Priv, [Head | Bs]}; gzipDeflate(Z, {Crc32,Size}, Bin, Flush) -> Bs = zlib:deflate(Z, Bin, Flush), {ok, Crc1} = crc32(Z, Crc32, Bin), Size1 = Size+size(Bin), Data = if Flush == finish -> % Appending should not % hurt, so let's be a % bit more consistent % here. Bs ++ [<>]; true -> Bs end, {ok, {Crc1, Size1}, Data}. %% like zlib:gzip/1, but returns an io list gzip(Data) -> gzip(Data, #deflate{}). gzip(Data, DOpts) when is_binary(Data) -> Z = zlib:open(), {ok, _, D} = gzipDeflate(Z, gzipInit(Z, DOpts), Data, finish), gzipEnd(Z), zlib:close(Z), {ok, D}; gzip(Data, DOpts) -> Z = zlib:open(), gzip_loop(Z, gzipInit(Z, DOpts), Data, [], []). gzip_loop(Z, P, [], [], A) -> {ok, _, D} = gzipDeflate(Z, P, <<>>, finish), gzipEnd(Z), zlib:close(Z), {ok, [A|D]}; gzip_loop(Z, P, B, C, A) when is_binary(B) -> {ok, P1, D} = gzipDeflate(Z, P, B, none), gzip_loop(Z, P1, C, [], case D of [] -> A; _ -> case A of [] -> D; _ -> [A|D] end end); gzip_loop(Z, P, [I|T], C, A) when is_integer(I) -> gzip_loop(Z, P, list_to_binary([I|T]), C, A); gzip_loop(Z, P, [H], C, A) -> gzip_loop(Z, P, H, C, A); gzip_loop(Z, P, [H|T], C, A) -> gzip_loop(Z, P, H, [T|C], A); gzip_loop(Z, P, [], C, A) -> gzip_loop(Z, P, C, [], A); gzip_loop(Z, P, I, C, A) when is_integer(I) -> gzip_loop(Z, P, <>, C, A). %% To work around a bug in zlib. crc32(Z, CRC, Binary) -> case port_control(Z, 17, <>) of [2,A,B,C,D] -> {ok, (A bsl 24)+(B bsl 16)+(C bsl 8)+D} end. yaws-2.0.2/src/yaws_ticker.erl0000664000175000017500000000047512605311412013241 00000000000000-module(yaws_ticker). -author('klacke@bluetail.com'). -export([ticker/3]). %% Moved here from module yaws to ease purging of yaws. %% cschultz ticker(Time, To, Msg) -> receive {'EXIT', _, _} -> exit(normal) after Time -> To ! Msg end, ?MODULE:ticker(Time, To, Msg). yaws-2.0.2/src/yaws_ls.erl0000664000175000017500000004040112605311412012367 00000000000000%% -*- coding: latin-1 -*- %%%---------------------------------------------------------------------- %%% File : yaws_ls.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 5 Feb 2002 by Claes Wikstrom %%% Modified: 13 Jan 2004 by Martin Bjorklund %%% Modified: Jan 2006 by Sébastien Bigot %%%---------------------------------------------------------------------- -module(yaws_ls). -author('klacke@hyber.org'). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). -include_lib("kernel/include/file.hrl"). -export([list_directory/6, out/1]). -define(FILE_LEN_SZ, 45). list_directory(_Arg, CliSock, List, DirName, Req, DoAllZip) -> {abs_path, Path} = Req#http_request.path, {DirStr, Pos, Direction, Qry} = parse_query(Path), ?Debug("List=~p Dirname~p~n", [List, DirName]), Descriptions = read_descriptions(DirName), L0 = lists:zf( fun(F) -> File = DirName ++ [$/|F], FI = file:read_file_info(File), file_entry(FI, DirName, F, Qry,Descriptions) end, List), L1 = lists:keysort(Pos, L0), L2 = if Direction == normal -> L1; Direction == reverse -> lists:reverse(L1) end, L3 = [Html || {_, _, _, _, Html} <- L2], Body = [ doc_head(DirStr), dir_header(DirName,DirStr), table_head(Direction), parent_dir(), if DoAllZip == true -> allzip(); DoAllZip == true_nozip -> []; true -> [] end, %% if DoAllGZip == true -> alltgz() end, %% if DoAllBZip2 == true -> alltbz2() end, %% if DoAllZip == true -> alltgz() end, %% if DoAllZip == true -> alltbz2() end, L3, table_tail(), dir_footer(DirName),%yaws:address(), doc_tail() ], B = list_to_binary(Body), %% Always use UTF-8 encoded file names. So, set the UTF-8 charset in the %% Content-Type header NewCT = case yaws:outh_get_content_type() of undefined -> "text/html; charset=utf-8"; CT0 -> [CT|_] = yaws:split_sep(CT0, $;), CT++"; charset=utf-8" end, yaws:outh_set_content_type(NewCT), yaws_server:accumulate_content(B), yaws_server:deliver_accumulated(CliSock), yaws_server:done_or_continue(). parse_query(Path) -> case string:tokens(Path, [$?]) of [DirStr, [PosC, $=, DirC] = Q] -> Pos = case PosC of $N -> 1; % name $M -> 2; % last modified $S -> 3; % size $D -> 4 % Description end, Dir = case DirC of $r -> reverse; _ -> normal end, {DirStr, Pos, Dir, "/?"++Q}; _ -> {Path, 1, normal, ""} end. parse_description(Line) -> L = string:strip(Line), Pos = string:chr(L,$ ), Filename = string:substr(L, 1, Pos-1), D = string:substr(L,Pos+1), Description = string:strip(D,left), {Filename,Description}. read_descriptions(DirName) -> File = filename:join(DirName, "MANIFEST.txt"), case file:read_file(File) of {ok,Bin} -> Lines = string:tokens(binary_to_list(Bin),"\n"), lists:map(fun parse_description/1,Lines); _ -> [] end. get_description(Name,Descriptions) -> case lists:keysearch(Name,1,Descriptions) of {value, {_,Description}} -> Description; _ -> [] end. doc_head(DirName) -> HtmlDirName = yaws_api:htmlize(yaws_api:url_decode(DirName)), ?F("\n" "\n" "\n" " \n" " Index of ~s\n" " \n" " \n" "\n", [HtmlDirName] ). doc_tail() -> "\n" "\n". table_head(Direction) -> NextDirection = if Direction == normal -> "r"; Direction == reverse -> "n" end, ["\n" " \n" " \n" " \n" " \n" " \n" " \n" " \n"]. table_tail() -> " \n" "
\"     \"/NameLast ModifiedSizeDescription


\n". dir_footer(DirName) -> File = DirName ++ [$/ | "README.txt"], case file:read_file(File) of {ok,Bin} -> "
\n" ++ binary_to_list(Bin) ++ "
\n"; _ -> yaws:address() end. dir_header(DirName,DirStr) -> File = DirName ++ [$/ | "HEADER.txt"], case file:read_file(File) of {ok,Bin} -> "
\n" ++ binary_to_list(Bin) ++ "
\n"; _ -> HtmlDirName = yaws_api:htmlize(yaws_api:url_decode(DirStr)), "

Index of " ++ HtmlDirName ++ "

\n" end. parent_dir() -> {Gif, Alt} = list_gif(directory,"."), ?F(" \n" " ~p/Parent Directory\n" " \n" " -\n" " \n" " \n", ["/icons/" ++ Gif, Alt ]). %% FIXME: would be nice with a good size approx. but it would require %% a deep scan of possibly the entire docroot, (and also some knowledge %% about zip's compression ratio in advance...) allzip() -> {Gif, Alt} = list_gif(zip,""), ?F(" \n" " ~p/all.zip\n" " \n" " -\n" " Build a zip archive of current directory\n" " \n", ["/icons/" ++ Gif, Alt]). %% alltgz() -> %% {Gif, Alt} = list_gif(zip,""), %% ?F(" \n" %% " ~p/all.tgz\n" %% " \n" %% " -\n" %% " Build a gzip archive of current directory\n" %% " \n", %% ["/icons/" ++ Gif, %% Alt]). %% alltbz2() -> %% {Gif, Alt} = list_gif(zip,""), %% ?F(" \n" %% " ~p/all.tbz2\n" %% " \n" %% " -\n" %% " Build a bzip2 archive of current directory\n" %% " \n", %% ["/icons/" ++ Gif, %% Alt]). is_user_dir(SP) -> case SP of [$/,$~ | T] -> User = string:sub_word(T,1,$/), case catch yaws:user_to_home(User) of {'EXIT', _} -> false; Home -> {true,Home} end; _ -> false end. out(A) -> SP = A#arg.server_path, PP = A#arg.appmod_prepath, Dir = case is_user_dir(SP) of {true,Home} -> Home ++ "/public_html"; false -> A#arg.docroot end ++ PP, %% {html,?F("

~p

",[Dir])}. YPid = self(), Forbidden_Paths = accumulate_forbidden_paths(), case filename:basename(A#arg.server_path) of "all.zip" -> spawn_link(fun() -> zip(YPid, Dir, Forbidden_Paths) end), {streamcontent, "application/zip", ""} %% "all.tgz" -> spawn_link(fun() -> tgz(YPid, Dir) end), %% {streamcontent, "application/gzip", ""}; %% "all.tbz2" -> spawn_link(fun() -> tbz2(YPid, Dir) end), %% {streamcontent, "application/gzip", ""} end. generate_random_fn() -> Bytes = try crypto:rand_bytes(64) of B when is_bitstring(B) -> B catch _:_ -> %% for installations without crypto << <<(random:uniform(256) - 1)>> || _ <- lists:seq(1,64) >> end, << Int:512/unsigned-big-integer >> = << Bytes/binary >>, integer_to_list(Int). mktempfilename([]) -> {error, no_temp_dir}; mktempfilename([Dir|R]) -> RandomFN = generate_random_fn(), Filename = filename:join(Dir, RandomFN), case file:open(Filename, [write]) of {ok, FileHandle} -> {ok, {Filename, FileHandle}}; _Else -> mktempfilename(R) end. mktempfilename() -> %% TODO: Add code to determine the temporary directory on various %% operating systems. PossibleDirs = ["/tmp", "/var/tmp"], mktempfilename(PossibleDirs). zip(YPid, Dir, ForbiddenPaths) -> {ok, RE_ForbiddenNames} = re:compile("\\.yaws\$"), Files = dig_through_dir(Dir, ForbiddenPaths, RE_ForbiddenNames), {ok, {Tempfile, TempfileH}} = mktempfilename(), file:write(TempfileH, lists:foldl(fun(I, Acc) -> Acc ++ I ++ "\n" end, [], Files)), file:close(TempfileH), process_flag(trap_exit, true), %% TODO: find a way to directly pass the list of files to %% zip. Erlang ports do not allow stdin to be closed %% independently; however, zip needs stdin to be closed as an %% indicator that the list of files is complete. P = open_port({spawn, "zip -q -1 - -@ < " ++ Tempfile}, [{cd, Dir},use_stdio, binary, exit_status]), F = fun() -> file:delete(Tempfile) end, stream_loop(YPid, P, F). accumulate_forbidden_paths() -> SC = get(sc), Auth = SC#sconf.authdirs, lists:foldl(fun({Path, _Auth}, Acc) -> Acc ++ [Path] end, [], Auth). %% tgz(YPid, Dir) -> %% process_flag(trap_exit, true), %% P = open_port({spawn, "tar cz ."}, %% [{cd, Dir},use_stdio, binary, exit_status]), %% stream_loop(YPid, P). %% tbz2(YPid, Dir) -> %% process_flag(trap_exit, true), %% P = open_port({spawn, "tar cj ."}, %% [{cd, Dir},use_stdio, binary, exit_status]), %% stream_loop(YPid, P). dir_contains_indexfile(_Dir, []) -> false; dir_contains_indexfile(Dir, [File|R]) -> case file:read_file_info(filename:join(Dir, File)) of {ok, _} -> true; _Else -> dir_contains_indexfile(Dir, R) end. dir_contains_indexfile(Dir) -> Indexfiles = [".yaws.auth", "index.yaws", "index.html", "index.htm"], dir_contains_indexfile(Dir, Indexfiles). dig_through_dir(Basedirlen, Dir, ForbiddenPaths, RE_ForbiddenNames) -> Dir1 = string:sub_string(Dir, Basedirlen), case {lists:member(Dir1, ForbiddenPaths), dir_contains_indexfile(Dir)} of {true,_} -> []; {_,true} -> []; {false, false} -> {ok, Files} = file:list_dir(Dir), lists:foldl(fun(I, Acc) -> Filename = filename:join(Dir, I), case {file:read_file_info(Filename), re:run(Filename, RE_ForbiddenNames)} of {_, {match, _}} -> Acc; {{ok, #file_info{type=directory}}, _} -> Acc ++ dig_through_dir( Basedirlen, Filename, ForbiddenPaths, RE_ForbiddenNames); {{ok, #file_info{type=regular}}, _} -> Acc ++ [string:sub_string( Filename, Basedirlen)]; _Else -> Acc %% Ignore other files end end, [], Files) end. dig_through_dir(Dir, ForbiddenPaths, RE_ForbiddenNames) -> dig_through_dir(length(Dir) + 1, Dir, ForbiddenPaths, RE_ForbiddenNames). stream_loop(YPid, P, FinishedFun) -> receive {P, {data, Data}} -> yaws_api:stream_chunk_deliver_blocking(YPid, Data), stream_loop(YPid, P, FinishedFun); {P, {exit_status, _}} -> yaws_api:stream_chunk_end(YPid), FinishedFun(); {'EXIT', YPid, Status} -> FinishedFun(), exit(Status); Else -> FinishedFun(), error_logger:error_msg("Could not deliver zip file: ~p\n", [Else]) end. file_entry({ok, FI}, _DirName, Name, Qry, Descriptions) -> ?Debug("file_entry(~p) ", [Name]), Ext = filename:extension(Name), {Gif, Alt} = list_gif(FI#file_info.type, Ext), QryStr = if FI#file_info.type == directory -> Qry; true -> "" end, %% Assume that all file names are UTF-8 encoded. If the VM uses ISO-latin-1 %% encoding, then no conversion is needed (file already returns the byte %% representation of file names). If the VM uses UTF-8, we need to do a %% little conversion to return the byte representation of file names. EncName = case file:native_name_encoding() of latin1 -> Name; utf8 -> binary_to_list(unicode:characters_to_binary(Name)) end, Description = get_description(Name,Descriptions), Entry = ?F(" \n" " ~p/~s\n" " ~s\n" " ~s\n" " ~s\n" " \n", ["/icons/" ++ Gif, Alt, yaws_api:url_encode(EncName) ++ QryStr, EncName, trim(EncName,?FILE_LEN_SZ), datestr(FI), sizestr(FI), Description]), ?Debug("Entry:~p", [Entry]), {true, {EncName, FI#file_info.mtime, FI#file_info.size, Description, Entry}}; file_entry(_Err, _, _Name, _, _) -> ?Debug("no entry for ~p: ~p", [_Name, _Err]), false. trim(L,N) -> trim(L,N,[]). trim([_H1,_H2,_H3]=[H|T], 3=I, Acc) -> trim(T, I-1, [H|Acc]); trim([_H1,_H2,_H3|_T], 3=_I, Acc) -> lists:reverse(Acc) ++ "..>"; trim([H|T], I, Acc) -> trim(T, I-1, [H|Acc]); trim([], _I, Acc) -> lists:reverse(Acc). %% FI -> 16-Jan-2006 23:06 datestr(FI) -> {{Year, Month, Day}, {Hour, Min, _}} = FI#file_info.mtime, io_lib:format("~s-~s-~w ~s:~s", [yaws:mk2(Day),yaws:month(Month),Year, yaws:mk2(Hour),yaws:mk2(Min)]). sizestr(FI) when FI#file_info.size > 1000000 -> ?F("~.1fM", [FI#file_info.size / 1000000]); sizestr(FI) when FI#file_info.size > 1000 -> ?F("~wk", [trunc(FI#file_info.size / 1000)]); sizestr(FI) when FI#file_info.size == 0 -> ?F("0k", []); sizestr(_FI) -> ?F("1k", []). % As apache does it... list_gif(directory, ".") -> {"back.gif", "[DIR]"}; list_gif(regular, ".txt") -> {"text.gif", "[TXT]"}; list_gif(regular, ".c") -> {"c.gif", "[   ]"}; list_gif(regular, ".dvi") -> {"dvi.gif", "[   ]"}; list_gif(regular, ".pdf") -> {"pdf.gif", "[   ]"}; list_gif(regular, _) -> {"layout.gif", "[   ]"}; list_gif(directory, _) -> {"dir.gif", "[DIR]"}; list_gif(zip, _) -> {"compressed.gif", "[DIR]"}; list_gif(_, _) -> {"unknown.gif", "[OTH]"}. yaws-2.0.2/src/haxe.erl0000664000175000017500000010374112605311412011642 00000000000000%%% Copyright (c) 2005-2006, A2Z Development USA, Inc. All Rights Reserved. %%% %%% The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is A2Z Development USA, Inc. %%% All Rights Reserved. %% This code was originally created for serializing/deserializing %% Erlang terms in JSON format. It was hacked to handle haXe %% (http://www.haxe.org) serialization/deserialization. %% %% Modified by Yariv Sadan (yarivvv@gmail.com) -module(haxe). -export([encode/1, encode/2, decode_string/1, decode_string/2, decode/1, decode/2, decode_next/1]). -export([get_left_over_chars/1]). -export([is_obj/1, obj_new/0, obj_fetch/2, obj_find/2, obj_is_key/2]). -export([test/0]). -export([obj_store/3, obj_from_list/1, obj_fold/3]). -author("Jim Larson , Robert Wai-Chi Chu "). -author("Gaspar Chilingarov , Gurgen Tumanyan "). -author("Yariv Sadan "). %%% This module translates haXe types into the following Erlang types: %%% %%% haXe Erlang %%% ---- ------ %%% int, float number %%% string (ascii, utf8) string %%% string (base64) binary %%% array {array, ElementList} %%% true, false, null atoms 't', 'f', and 'n' %%% Number.NaN atom 'nan' %%% Number.NEGATIVE_INFINITY atom 'neg_infinity' %%% Number.POSITIVE_INFINITY atom 'infinity' %%% object tagged proplist with string (or atom) keys %%% (e.g. {struct, [{foo, "bar"}, {baz, 4}]} ) %%% class object NOT SUPPORTED %%% enum NOT SUPPORTED %%% reference {ref, Idx}, Idx -> int() %%% exception {exception, Obj}, Obj is any %%% of the haXe types above %%% %%% Classs objects and Enums are currently not supported %%% because simulating such types in Erlang is quite cumbersome, plus %%% anonymous objects should be sufficient for most RPC needs. %%% (If you strongly believe otherwise, contact me at yarivvv@gmail.com %%% and I will consider adding class/enum support in a future version). %%% %%% References are handled transparently by the encoding/decoding %%% functions. The decoding functions automatically expand %%% references, and the encoding functions automatically serialize %%% a string as a reference if an equal string has already been %%% serialized (note: the haXe serializer can reference strings, %%% arrays and objects, but the Erlang encoder only references %%% strings due to the lack of address comparison in Erlang). %%% %%% If you wish to avoid expensive string comparisons %%% in the encoder, or to have references to non-string objects, %%% you can define a reference explicitly as a %%% {ref, Idx} tuple. However, this usage is confusing and %%% error prone, so it's better to avoid it except in extreme %%% cases. -define(L(Obj), io:format("~s:~w: ~w\n", [?MODULE, ?LINE, Obj])). encode({ref, _Idx} = Ref) -> encode_basic(Ref); encode(Obj) -> encode(Obj, true, 2). %% The second parameter is a list of options. %% The following options are available: %% {use_cache, boolean()} -- default = true %% {haxe_version, Vsn} -- default = 2, can be 1 or 2 %% %% The haxe_version is a rough indication of what haXe version we %% should encode to. This does not really capture the different %% encodings used in the different haXe 1.x versions, see the %% token_identifier function in this module for details. %% %% There second parameter can also be a boolean for backwards compatibility, %% in which case the latest haxe_version (2) is assumed. encode(Obj, Opts) when is_list(Opts) -> UseCache = proplists:get_value(use_cache, Opts, true), Vsn = proplists:get_value(haxe_version, Opts, 2), encode(Obj, UseCache, Vsn); % function clauses for backwards compatibility: encode(Obj, true=UseCache) -> encode(Obj, UseCache, 2); encode(Obj, false=UseCache) -> encode(Obj, UseCache, 2). %% The second parameter, if a boolean, indicates whether the cache should %% be used. By default, it's turned on (this follows the default configuration %% in haXe). encode(Obj, true, Vsn) -> {Result, _Cache} = encode(Obj, dict:new(), Vsn), Result; encode(Obj, false, Vsn) -> {Result, _Cache} = encode(Obj, undefined, Vsn), Result; encode(L, Cache, _Vsn=1) when is_list(L) -> case is_string(L) of yes -> encode_string1(L, $s, Cache); unicode -> encode_string1(xmerl_ucs:to_utf8(L), $j, Cache); no -> exit({error, {haxe_encode, {not_string, L}}}) end; encode(L, Cache, _Vsn=2) when is_list(L) -> case is_string(L) of no -> exit({error, {haxe_encode, {not_string, L}}}); _ -> L2 = yaws_api:url_encode(xmerl_ucs:to_utf8(L)), encode_string1(L2, $y, Cache) end; encode({array, Props}, Cache, Vsn) -> encode_array(Props, Cache, Vsn); encode({struct, Props}, Cache, Vsn) -> encode_object(Props, Cache, Vsn); encode({exception, E}, Cache, Vsn) -> {Result, Cache2} = encode(E, Cache, Vsn), {[$x | Result], Cache2}; encode(Term, Cache, _Vsn) -> case encode_basic(Term) of {error, _Err} = Err -> exit(Err); Result -> {Result, Cache} end. encode_basic(Term) -> case Term of true -> "t"; false -> "f"; null -> "n"; undefined -> "n"; {ref, Idx} -> [$r | integer_to_list(Idx)]; nan -> "k"; infinity -> "p"; neg_infinity -> "m"; 0 -> "z"; I when is_integer(I) -> [$i | integer_to_list(I)]; F when is_float(F) -> [$d | io_lib:format("~g", [F])]; B when is_binary(B) -> S = binary_to_list(base64:encode(B)), [$s, integer_to_list(length(S)), $: | S]; _ -> {error, {bad_term, Term}} end. %% Find a string in the list of previously encoded string %% end return {true, {ref, Idx}}, if the search succeeded, %% where Idx is the value associated with the string. %% Otherwise, return 'false'. find_ref(_Str, undefined) -> false; find_ref(Str, CacheDict) -> case dict:find(Str, CacheDict) of error -> false; {ok, Idx} -> {true, Idx} end. %% Encode an Erlang string to haXe. encode_string(Str, Cache, 1=_Vsn) -> encode_string1(Str, $s, Cache); encode_string(Str, Cache, 2=_Vsn) -> encode_string1(Str, $y, Cache). encode_string1(Str, FirstChar, Cache) -> case find_ref(Str, Cache) of false -> {ok, Result} = encode_string2(Str, FirstChar), NewCache = case Cache of undefined -> undefined; _ -> dict:store(Str, dict:size(Cache), Cache) end, {Result, NewCache}; {true, Idx} -> {[$R | integer_to_list(Idx)], Cache} end. encode_string2(S, $y) -> {ok, [$y, integer_to_list(length(S)), $: | S]}; encode_string2(S, FirstChar) -> encode_string2(S, FirstChar, []). encode_string2([], FirstChar, Acc) -> Str = lists:reverse(Acc), Len = integer_to_list(length(Str)), {ok, [FirstChar, Len, $: | Str]}; encode_string2([C | Cs], FirstChar, Acc) -> case C of $\\ -> encode_string2(Cs, FirstChar, [$\\, $\\ | Acc]); $\n -> encode_string2(Cs, FirstChar, [$n, $\\ | Acc]); $\r -> encode_string2(Cs, FirstChar, [$r, $\\ | Acc]); C when C =< 16#FFFF -> encode_string2(Cs, FirstChar, [C | Acc]); _ -> exit({error, {haxe_encode, {bad_char, C}}}) end. encode_object(Props, Cache, Vsn) -> {Result, Cache2} = encode_object_rest(Props, Cache, Vsn), {[$o | Result], Cache2}. encode_object_rest(Props, Cache, Vsn) -> {EncodedProps, Cache1} = lists:foldl( fun({Key, Value}, {Acc, Cache2}) -> {EncodedKey, Cache3} = case Key of L when is_list(L) -> encode_string(L, Cache2, Vsn); A when is_atom(A) -> encode_string(atom_to_list(A), Cache2, Vsn); _ -> exit({error, {haxe_encode, {bad_key, Key}}}) end, {EncodedVal, Cache4} = encode(Value, Cache3, Vsn), case Acc of [] -> {[[EncodedKey, EncodedVal]], Cache4}; _ -> {[[EncodedKey, EncodedVal] | Acc], Cache4} end end, {[], Cache}, Props), Result = [lists:reverse(EncodedProps), $g], {Result, Cache1}. encode_array(Props, Cache, Vsn) -> {NullCount, Arr, Cache1} = lists:foldl( fun (Elem, {NullCount, Arr, Cache2}) when Elem == null; Elem == undefined -> {NullCount+1, Arr, Cache2}; (Elem, {0, Arr, Cache2}) -> {Encoded, Cache3} = encode(Elem, Cache2, Vsn), {0, [Encoded | Arr], Cache3}; (Elem, {NullCount, Arr, Cache2}) -> {Encoded, Cache3} = encode(Elem, Cache2, Vsn), {0, [Encoded, encode_nulls(NullCount) | Arr], Cache3} end, {0, [$a], Cache}, Props), {lists:reverse([$h , encode_nulls(NullCount) | Arr]), Cache1}. encode_nulls(0) -> []; encode_nulls(1) -> [$n]; encode_nulls(Num) -> [$u | integer_to_list(Num)]. %%% SCANNING %%% %%% Scanning funs return either: %%% {done, Result, LeftOverChars} %%% if a complete token is recognized, or %%% {more, Continuation} %%% if more input is needed. %%% Result is {ok, Term}, 'eof', or {error, Reason}. %%% Here, the Continuation is a simple Erlang string. %%% %%% Currently, error handling is rather crude - errors are recognized %%% by match failures. EOF is handled only by number scanning, where %%% it can delimit a number, and otherwise causes a match failure. %%% token_vsn1([]) -> {more, []}; token_vsn1(eof) -> {done, eof, []}; token_vsn1([C | Rest]) -> case token_identifier(1, C) of int -> scan_int(Rest); float -> scan_float(Rest); string -> scan_string(Rest); utf8 -> scan_utf8(Rest); error -> {done, {error, invalid_token}, Rest}; Token -> {done, {ok, Token}, Rest} end. token_vsn2([]) -> {more, []}; token_vsn2(eof) -> {done, eof, []}; token_vsn2([C | Rest]) -> case token_identifier(2, C) of int -> scan_int(Rest); float -> scan_float(Rest); string -> scan_string(Rest); url_encoded_string -> scan_url_encoded_string(Rest); base64_bytes -> scan_base64_bytes(Rest); error -> {done, {error, invalid_token}, Rest}; Token -> {done, {ok, Token}, Rest} end. token_identifier(Vsn, C) -> case C of $i -> int; $d -> float; $s -> case Vsn of 1 -> string; 2 -> base64_bytes %% redefined to bytes (base64) in haXe 2.0 end; $j -> case Vsn of 1 -> utf8; 2 -> enum %% redefined from utf8 to enum in haXe 1.16 end; $n -> null; $t -> true; $f -> false; $z -> 0; $k -> nan; $p -> infinity; $m -> neg_infinity; $a -> array; $h -> array_end; $o -> obj; $c -> class; $g -> obj_end; $r -> ref; $R -> str_ref; $x -> exception; $y -> case Vsn of 1 -> error; 2 -> url_encoded_string %% utf8; added/defined in haXe 1.11 end; %% this token is only valid as an element %% of an array $u -> null_seq; _ -> error end. scan_utf8(Chars) -> scan_chars(Chars, utf8). scan_string(Chars) -> scan_chars(Chars, string). scan_url_encoded_string(Chars) -> scan_chars(Chars, url_encoded). scan_base64_bytes(Chars) -> scan_chars(Chars, base64_bytes). scan_chars(Chars, Type) -> case scan_int(Chars) of {done, {ok, _NumBytes}, []} -> {more, Chars}; {done, {ok, _NumBytes}, [C | _Rest]} when C /= $: -> {done, {error, bad_char, C}, Chars}; {done, {ok, NumBytes}, [_ | Rest]} when length(Rest) >= NumBytes -> case Type of utf8 -> NewStr = xmerl_ucs:from_utf8(lists:sublist(Rest, NumBytes)), scan_chars(NewStr, [], length(NewStr)); string -> scan_chars(Rest, [], NumBytes); url_encoded -> {S, Rest2} = split_str_after(Rest, NumBytes), S2 = xmerl_ucs:from_utf8(yaws_api:url_decode_with_encoding(S, latin1)), {done, {ok, S2}, Rest2}; base64_bytes -> {S, Rest2} = split_str_after(Rest, NumBytes), {done, {ok, base64:decode(S)}, Rest2} end; {done, {ok, _NumBytes}, _Rest} -> {more, Chars}; Other -> Other end. scan_chars(Rest, A, 0) -> {done, {ok, lists:reverse(A)}, Rest}; scan_chars([$\\] = Chars, _A, 0) -> {done, {error, missing_escape_character}, Chars}; scan_chars([$\\, C | Rest], A, NumLeft) -> scan_chars(Rest, [esc_to_char(C) | A], NumLeft - 2); scan_chars([C | Rest], A, NumLeft) -> scan_chars(Rest, [C | A], NumLeft - 1). esc_to_char(C) -> case C of $n -> $\n; $r -> $\r; $\\ -> $\\ end. split_str_after(S, AfterNumBytes) -> {string:substr(S, 1, AfterNumBytes), string:substr(S, AfterNumBytes + 1)}. scan_float(Chars) -> scan_number(Chars, float). scan_int(Chars) -> scan_number(Chars, int). scan_number([], _Type) -> {more, []}; scan_number(eof, _Type) -> {done, {error, incomplete_number}, []}; scan_number([$-, $- | _Rest] = Input, _Type) -> {done, {error, invalid_number}, Input}; scan_number([$- | Ds] = Input, Type) -> case scan_number(Ds, Type) of {more, _Cont} -> {more, Input}; {done, {ok, N}, CharList} -> {done, {ok, -1 * N}, CharList}; {done, Other, Chars} -> {done, Other, Chars} end; scan_number([D | Ds] = Input, Type) when D >= $0, D =< $9 -> scan_number(Ds, D - $0, Input, Type). %% Numbers don't have a terminator, so stop at the first non-digit, %% and ask for more if we run out. scan_number([], _Num, X, _Type) -> {more, X}; scan_number(eof, Num, _X, _Type) -> {done, {ok, Num}, eof}; scan_number([$.], _Num, X, float) -> {more, X}; scan_number([$., D | Ds], Num, X, float) when D >= $0, D =< $9 -> scan_fraction([D | Ds], Num, X); scan_number([D | Ds], Num, X, Type) when Num > 0, D >= $0, D =< $9 -> % Note that nonzero numbers can't start with "0". scan_number(Ds, 10 * Num + (D - $0), X, Type); scan_number([D | Ds], Num, X, float) when D == $E; D == $e -> scan_exponent_begin(Ds, float(Num), X); scan_number([D | _] = Ds, Num, _X, _Type) when D < $0; D > $9 -> {done, {ok, Num}, Ds}. scan_fraction(Ds, I, X) -> scan_fraction(Ds, [], I, X). scan_fraction([], _Fs, _I, X) -> {more, X}; scan_fraction(eof, Fs, I, _X) -> R = I + list_to_float("0." ++ lists:reverse(Fs)), {done, {ok, R}, eof}; scan_fraction([D | Ds], Fs, I, X) when D >= $0, D =< $9 -> scan_fraction(Ds, [D | Fs], I, X); scan_fraction([D | Ds], Fs, I, X) when D == $E; D == $e -> R = I + list_to_float("0." ++ lists:reverse(Fs)), scan_exponent_begin(Ds, R, X); scan_fraction(Rest, Fs, I, _X) -> R = I + list_to_float("0." ++ lists:reverse(Fs)), {done, {ok, R}, Rest}. scan_exponent_begin(Ds, R, X) -> scan_exponent_begin(Ds, [], R, X). scan_exponent_begin([], _Es, _R, X) -> {more, X}; scan_exponent_begin(eof, _Es, _R, X) -> {done, {error, missing_exponent}, X}; scan_exponent_begin([D | Ds], Es, R, X) when D == $-; D == $+; D >= $0, D =< $9 -> scan_exponent(Ds, [D | Es], R, X). scan_exponent([], _Es, _R, X) -> {more, X}; scan_exponent(eof, Es, R, _X) -> X = R * math:pow(10, list_to_integer(lists:reverse(Es))), {done, {ok, X}, eof}; scan_exponent([D | Ds], Es, R, X) when D >= $0, D =< $9 -> scan_exponent(Ds, [D | Es], R, X); scan_exponent(Rest, Es, R, _X) -> X = R * math:pow(10, list_to_integer(lists:reverse(Es))), {done, {ok, X}, Rest}. %%% PARSING %%% %%% The decode function takes a char list as input, but %%% interprets the end of the list as only an end to the available %%% input, and returns a "continuation" requesting more input. %%% When additional characters are available, they, and the %%% continuation, are fed into decode/2. You can use the atom 'eof' %%% as a character to signal a true end to the input stream, and %%% possibly flush out an unfinished number. The decode_string/1 %%% function appends 'eof' to its input and calls decode/1. %%% %%% Parsing and scanning errors are handled only by match failures. %%% The external caller must take care to wrap the call in a "catch" %%% or "try" if better error-handling is desired. Eventually parse %%% or scan errors will be returned explicitly with a description, %%% and someday with line numbers too. %%% %%% The parsing code uses a continuation-passing style to allow %%% for the parsing to suspend at any point and be resumed when %%% more input is available. %%% See http://en.wikipedia.org/wiki/Continuation_passing_style %% Return the first haXe value decoded from the input string. %% The string must contain at least one complete haXe value. %% %% The second (optional) parameter can be either: %% - a list of options: %% {use_cache, boolean()} -- default = true %% {haxe_version, Vsn} -- default = 2, can be 1 or 2 %% - a continuation, if {more,Continuation} was previously %% returned and you now have more characters %% - a boolean specifying whether to use the cache, %% for backwards compatibility %% %% The haxe_version is a rough indication of what haXe version we %% should expect to decode. This does not really capture the different %% encodings used in the different haXe 1.x versions, see the %% token_identifier function in this module for details. %% %% There second parameter can also be a boolean for backwards compatibility, %% in which case the latest haxe_version (2) is assumed. %% %% Caching is on by default, but it can be turned %% off for performance and lower memory consumption depending %% on the content of the messages. decode_string(CharList) -> decode_string(CharList, [{use_cache, true}]). decode_string(CharList, Opts) -> {done, V, _} = decode(CharList ++ [eof], Opts), V. %% Attempt to decode a haXe value from the input string %% and continuation, using an empty initial continuation. %% Return {done, Result, Continuation} if a value is recognized, %% or {more, Continuation} if more input characters are needed. %% The Result can be {ok, Value}, eof, or {error, Reason}. %% The Continuation is then fed as an argument to decode/2 when %% more input is available. %% Use the atom 'eof' instead of a char list to signal %% a true end to the input, and may flush a final number. %% %% Use the get_left_over_chars/1 function to retrieve any non-consumed %% characters in the continuation. decode(CharList) -> decode_o(CharList, [{use_cache, true}]). -record(cont,{chars, cache, tokenizer}). decode(CharList, Opts) when is_list(Opts) -> decode_o(CharList, Opts); decode(CharList, Cont) when is_record(Cont, cont) -> %% Continuation case #cont{chars = Chars, cache = Cache, tokenizer = Tokenizer} = Cont, decode2(Chars ++ CharList, Cache, Tokenizer); decode(CharList, true) -> %% function clause for backwards compatibility decode_o(CharList, [{use_cache, true}]); decode(CharList, false) -> %% function clause for backwards compatibility decode_o(CharList, [{use_cache, false}]). decode_o(CharList, Opts) -> %% Note: our Cache for decoding is the tuple %% {ObjCache::list(), StringCache::dict()} Cache = case proplists:get_value(use_cache, Opts, true) of true -> {[], dict:new()}; false -> undefined end, Tokenizer = case proplists:get_value(haxe_version, Opts, 2) of 2 -> fun token_vsn2/1; 1 -> fun token_vsn1/1 %% haxe uses "old_serializer" end, decode2(CharList, Cache, Tokenizer). decode2(CharList, Cache, Tokenizer) -> Cont = #cont{chars = CharList, cache = Cache, tokenizer = Tokenizer}, get_token(Cont, fun first_cont_fun/2). decode_next(Cont) -> get_token(Cont, fun first_cont_fun/2). get_left_over_chars(#cont{chars=Cs}) -> Cs. first_cont_fun(eof, Cs) -> {done, eof, Cs}; first_cont_fun(T, Cs) -> parse_value(T, Cs, fun(V, C2) -> {done, {ok, V}, C2} end). %% Continuation Kt must accept (TokenOrEof, {Chars, Cache, Tokenizer}) get_token(C = #cont{chars=Chars, tokenizer=Tokenizer}, Kt) -> case Tokenizer(Chars) of {done, {ok, T}, Rest} -> Kt(T, C#cont{chars=Rest}); {done, eof, Rest} -> Kt(eof, C#cont{chars=Rest}); {done, {error, Reason}, Rest} -> {done, {error, Reason}, C#cont{chars=Rest}}; {more, X} -> {more, C#cont{chars=X}} end. %% Continuation Kv must accept (Value, {Chars, Cache, Tokenizer}) parse_value(Token, C, Kv) -> parse_value(Token, C, Kv, false). parse_value(Token, #cont{cache=Cache} = C, Kv, AcceptNullSeq)-> case Token of eof -> {done, {error, premature_eof}, C}; T when T == null; T == true; T == false; T == nan; T == infinity; T == neg_infinity -> Kv(T, C); obj -> parse_object(C, Kv); class -> parse_class(C, Kv); array -> parse_array(C, Kv); enum -> parse_enum(C, Kv); exception -> parse_exception(C, Kv); ref -> parse_ref(C, Kv); str_ref -> parse_ref(C, Kv, true); null_seq when AcceptNullSeq -> parse_null_seq(C, Kv); Str when is_list(Str) -> Kv(Str, C#cont{cache=put_str(Str, Cache)}); Num when is_number(Num) -> Kv(Num, C); B when is_binary(B) -> Kv(B, C#cont{cache=put_str(B, Cache)}); X -> {done, {error, syntax_error,X}, C} end. parse_class(Chars, _Kv) -> {done, {error, class_objects_not_supported}, Chars}. parse_object(Chars, Kv) -> parse_object(Chars, Kv, obj_new()). parse_object(C, Kv, Obj) -> get_token(C, fun(T, C2=#cont{cache=Cache}) -> case T of obj_end -> NewCache = put_obj(Obj, Cache), Kv(Obj, C2#cont{cache=NewCache}); _ -> NewCache = put_obj(placeholder, Cache), parse_object_field( Obj, T, C2#cont{cache=NewCache}, Cache, Kv) end end). put_obj(_xObj, undefined) -> undefined; put_obj(Obj, {ObjCache, StrCache}) -> {[Obj | ObjCache], StrCache}. put_str(_Str, undefined) -> undefined; put_str(Str, {ObjCache, StrCache}) -> {ObjCache, dict:store(dict:size(StrCache), Str, StrCache)}. parse_object_field(_Obj, eof, C, _OrigCache, _Kv) -> {done, {error, premature_eof}, C}; %% if the key is a reference, we deference it and continue parse_object_field(Obj, RefType, C, OrigCache, Kv) when RefType == ref; RefType == str_ref -> parse_ref(C, fun(Key, C1) -> parse_object_val(Obj, Key, C1, OrigCache, Kv) end, RefType == str_ref); %% if the key is a string, we put it in the cache and continue parse_object_field(Obj, Field, C=#cont{cache=Cache}, OrigCache, Kv) when is_list(Field) -> NewCache = put_str(Field, Cache), parse_object_val(Obj, Field, C#cont{cache=NewCache}, OrigCache, Kv). parse_object_val(Obj, Field, C, OrigCache, Kv) when is_list(Field) -> get_token(C, fun(T, C2) -> parse_value (T, C2, fun(Val, C3) -> Obj2 = obj_store(Field, Val, Obj), parse_object_next(Obj2, C3, OrigCache, Kv) end) end); parse_object_val(_Obj, Field, C, _OrigCache, _Kv) -> {done, {error, {member_name_not_string, Field}}, C}. parse_object_next({struct, Props} = Obj, C, OrigCache, Kv) -> get_token(C, fun (obj_end, C1 = #cont{cache=Cache}) -> Obj1 = {struct, lists:reverse(Props)}, Cache1 = append_new_elems( Cache, Obj1, OrigCache), Kv(Obj1, C1#cont{cache=Cache1}); (eof, C1) -> {done, {error, premature_eof}, C1}; (T, C1) -> parse_object_field(Obj, T, C1, OrigCache, Kv) end). append_new_elems(undefined, _Obj, _Cache) -> undefined; append_new_elems({TempObjCache, NewStrCache}, Obj, {ObjCache, _OrigStrCache}) -> ObjCache1 = [Obj | ObjCache], NumNewElts = length(TempObjCache) - length(ObjCache1), NewElts = lists:sublist(TempObjCache, NumNewElts), {NewElts ++ ObjCache1, NewStrCache}. parse_array(C = #cont{cache=Cache}, Kv) -> %% We need to put a temporary placeholder in the cache %% to comply with haXe's indexing scheme, which assumes %% the array is put in the cache *before* its members. %% When we finish parsing the array, we collect the new %% cache entries and put them in the old cache after %% first inserting the fully parsed array. %% %% If it sounds backwards, well, it is! :) parse_array([], C#cont{cache=put_obj(placeholder, Cache)}, Cache, Kv). parse_array(Elems, C, OrigCache, Kv) -> get_token(C, fun (eof, C1) -> {done, {error, premature_eof}, C1}; (array_end, C1=#cont{cache=Cache1}) -> Arr = {array, lists:reverse(Elems)}, Cache2 = append_new_elems( Cache1, Arr, OrigCache), Kv(Arr, C1#cont{cache=Cache2}); (T, C1) -> parse_array_tok(Elems, T, C1, OrigCache, Kv) end). parse_array_tok(Elems, T, Cont, OrigCache, Kv) -> parse_value(T, Cont, fun({null_seq, Nulls}, C1) -> parse_array(Nulls ++ Elems, C1, OrigCache, Kv); (V, C1) -> parse_array([V | Elems], C1, OrigCache, Kv) end, true). parse_enum(Chars, _Kv) -> {done, {error, enums_not_supported}, Chars}. %% it's safe to assume we'll never have to parse exceptions %% on the server side, but this function is here for completeness parse_exception(Cont, Kv) -> get_token(Cont, fun(T, C1) -> parse_value(T, C1, fun(Val, C2) -> Kv({exception, Val}, C2) end) end). %%% The next three functions help with storing references %%% to deserialized objects for future lookup during decoding parse_ref(Cont, Kv) -> parse_ref(Cont, Kv, false). parse_ref(C=#cont{chars=Chars}, Kv, IsStrRef) -> case scan_int(Chars) of {done, {ok, Idx}, Chars1} -> parse_ref2(IsStrRef, C#cont{chars=Chars1}, Idx, Kv); Other -> Other end. parse_ref2(_IsStrRef, #cont{cache=undefined} = Cont, _Idx, _Kv) -> {done, {error, references_disabled}, Cont}; parse_ref2(false, #cont{cache={ObjCache, _StrCache}} = Cont, Idx, Kv) -> if Idx > length(ObjCache) -> {done, {error, {ref_idx_out_of_bounds, Idx}}, Cont}; true -> Val = lists:nth(length(ObjCache) - Idx, ObjCache), if Val == placeholder -> {done, {error, {illegal_ref, Idx}}, Cont}; true -> Kv(Val, Cont) end end; parse_ref2(true, #cont{cache={_ObjCache, StrCache}} = Cont, Idx, Kv) -> Cond = Idx + 1 > dict:size(StrCache), if Cond -> {done, {error, {str_ref_idx_out_of_bounds, Idx}}, Cont}; true -> {ok, Val} = dict:find(Idx, StrCache), Kv(Val, Cont) end. parse_null_seq(Cont = #cont{chars=Chars}, Kv) -> case scan_int(Chars) of {done, {ok, Num}, C1} when Num > 0 -> Cont1 = Cont#cont{chars=C1}, Kv({null_seq, lists:duplicate(Num, null)}, Cont1); Other -> Other end. %%% OBJECTS %%% %%% We'll use tagged property lists as the internal representation %%% of haXe objects. Unordered lists perform worse than trees for %%% lookup and modification of members, but we expect objects to be %%% have only a few members. Lists also print better. is_obj(_) -> false. %% create a simple haXe object obj_new() -> {struct, []}. %% Fetch an object member's value, expecting it to be in the object. %% Return value, runtime error if no member found with that name. obj_fetch(Key, {struct, Props}) -> case proplists:get_value(Key, Props) of undefined -> exit({struct_no_key, Key}); Value -> Value end. %% Fetch an object member's value, or indicate that there is no such member. %% Return {ok, Value} or 'error'. obj_find(Key, {struct, Props}) -> case proplists:get_value(Key, Props) of undefined -> error; Value -> {ok, Value} end. obj_is_key(Key, {struct, Props}) -> proplists:is_defined(Key, Props). %% Store a new member in an object. Returns a new object. obj_store(KeyStr, Value, {struct, Props}) -> Key = list_to_atom(KeyStr), NewProps = [{Key, Value} | proplists:delete(Key, Props)], {struct, NewProps}. %% Create an object from a list of Key/Value pairs. obj_from_list(Props) -> {struct, {Props}}. %% Fold Fun across object, with initial accumulator Acc. %% Fun should take (Value, Acc) as arguments and return Acc. obj_fold(Fun, Acc, {struct, Props}) -> lists:foldl(Fun, Acc, Props). is_string([]) -> yes; is_string(List) -> is_string(List, non_unicode). is_string([C|Rest], non_unicode) when C >= 0, C =< 255 -> is_string(Rest, non_unicode); is_string([C|Rest], _) when C =< 65000 -> is_string(Rest, unicode); is_string([], non_unicode) -> yes; is_string([], unicode) -> unicode; is_string(_, _) -> no. test() -> Tests = [ {1, "i1"}, {1.1, "d1.10000"}, {"foo", "y3:foo"}, %% todo test utf8 {null, "n"}, {true, "t"}, {false, "f"}, {0, "z"}, {nan, "k"}, {infinity, "p"}, {neg_infinity, "m"}, {{array, [1,2,3]}, "ai1i2i3h"}, {{array, [null]}, "anh"}, {{array, [null, null]}, "au2h"}, {{array, [3, 4, null, null, null, 5, null]}, "ai3i4u3i5nh"}, {{struct, [{foo, "bar"}, {baz, "boing"}]}, "oy3:fooy3:bary3:bazy5:boingg"}, {{array, ["foo", "bar", "foo", {struct, [{bar, "baz"}, {foo, 123}]}]}, "ay3:fooy3:bary3:foooy3:bary3:bazy3:fooi123gh"}, {{exception, "bad"}, "xy3:bad"} ], {Passed, Failed} = run_tests(Tests, false), Tests1 = [ {{array, ["foo", "bar", "foo"]}, "ay3:fooy3:barR0h"}, {{struct, [{foo, "bar"}, {bar, "foo"}]}, "oy3:fooy3:barR1R0g"}, {{array, ["foo", "bar", "foo", {struct, [{bar, "baz"}, {foo, 123}]}]}, "ay3:fooy3:barR0oR1y3:bazR0i123gh"} ], {Passed1, Failed1} = run_tests(Tests1, true), Tests2 = [{"abc"++[16#e5,16#e4,16#f6], %% a-ring,a-diaeresis,o-diaeresis "y21:abc%C3%A5%C3%A4%C3%B6"}, %% url-encoded utf8 {<<"abc">>, "s4:YWJj"}], {Passed2, Failed2} = run_tests(Tests2, [{haxe_version,2}]), %% version1 encode/decode (simple utf8) %% This is mostly based on looking at the code of the haxe %% Serializer.hx and Unserializer.hx (as of cvs-tag v1-10) Tests3 = [{"abc\n"++[16#1e5,16#1e4,16#1f6], "j11:abc\\n"++[16#c7,16#a5,16#c7,16#a4,16#c7,16#b6]}, {"abc", "s3:abc"}], {Passed3, Failed3} = run_tests(Tests3, [{haxe_version,1}]), io:format("passed: ~w, failed: ~w\n", [Passed + Passed1 + Passed2 + Passed3, Failed + Failed1 + Failed2 + Failed3]). run_tests(Tests, EnableReferences) -> lists:foldl( fun({Term, Str}, Agg) -> Encoded = lists:flatten(encode(Term,EnableReferences)), {ok, Decoded} = decode_string(Str,EnableReferences), Check = fun(Val1, Val2, {P, F}) -> case Val1 == Val2 of true -> {P + 1, F}; _ -> {P, F + 1} end end, Agg1 = Check(Str, Encoded, Agg), Agg2 = Check(Term, Decoded, Agg1), io:format("~s == ~s\n~w\n~w == ~w\n~w\n\n", [Str, Encoded, Str == Encoded, Term, Decoded, Term == Decoded]), Agg2 end, {0, 0}, Tests). yaws-2.0.2/src/yaws.app.src.script0000664000175000017500000000230512605311412013761 00000000000000%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ft=erlang ts=4 sw=4 et AppDeps = case os:getenv("YAWS_APPDEPS") of false -> []; AppDeps0 -> string:tokens(AppDeps0, " ,") end, AppDepsList = ","++string:join(AppDeps, ","), %% generate src/yaws_appdeps.hrl from src/yaws_appdeps.hrl.in Dir = filename:dirname(SCRIPT), InFile = filename:join(Dir, "yaws_appdeps.hrl.in"), OutFile = filename:join(Dir, "yaws_appdeps.hrl"), {ok, AppHrl0} = file:read_file(InFile), AppHrl = binary:replace(AppHrl0, <<"@APPDEPS@">>, list_to_binary(AppDepsList)), ok = file:write_file(OutFile, AppHrl), %% replace @APPDEPS@ in application dependencies with any apps specified in %% the YAWS_APPDEPS OS env var [{application,yaws,Cfg}] = CONFIG, {applications,Apps0} = lists:keyfind(applications, 1, Cfg), Apps = lists:flatmap(fun('stdlib@APPDEPS@') -> [stdlib]++[list_to_atom(A) || A <- AppDeps]; (A) -> [A] end, Apps0), [{application,yaws,lists:keyreplace(applications, 1, Cfg, {applications, Apps})}]. yaws-2.0.2/src/yaws_pam.erl0000664000175000017500000002332112605311412012530 00000000000000%%%------------------------------------------------------------------- %%% File : yaws_pam.erl %%% Author : %%% Description : %%% %%% Created : 20 Dec 2005 by %%%------------------------------------------------------------------- -module(yaws_pam). -behaviour(gen_server). %%-------------------------------------------------------------------- %% External exports -export([start_link/0, start_link/3 ]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([auth/2, close/1]). -define(TO, (1000 * 60 * 3)). -record(user, {i, %% sid from, %% pid ref}).%% monitorref -record(state, {i, port, mode, sids = [], % active sessions [#user{}] srv, reqs = [] % outstandig requests [#user{}] }). %%==================================================================== %% External functions %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link/0 %% Description: Starts the server %%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). start_link(Service, UseAccounting, UseSess) -> Args = [Service, UseAccounting, UseSess], gen_server:start_link({local, ?MODULE}, ?MODULE, Args, []). auth(User, Password) -> case has_nul(User) or has_nul(Password) of false -> try gen_server:call(?MODULE, {auth, User, Password}, 15000) of Ret -> Ret catch _:_ -> {no, {"auth", "timeout"}} end; true -> %% PAM can't handle embedded NUL (nor can the "port protocol") %% - and it's probably a DOS attempt anyway, do a delay timer:sleep(1000), {no, {"auth", "Authentication failure"}} end. %% yaws never use close, ... no session mgmt in yaws close(Handle) -> gen_server:call(?MODULE, {close, Handle}, infinity). has_nul(<>) -> lists:member(0, binary_to_list(B)); has_nul(L) -> lists:member(0, L). %%==================================================================== %% Server functions %%==================================================================== %%-------------------------------------------------------------------- %% Function: init/1 %% Description: Initiates the server %% Returns: {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %%-------------------------------------------------------------------- init([]) -> {Srv, Act,Sess} = {okundef(application:get_env(pam_service)), okundef(application:get_env(pam_use_acct)), okundef(application:get_env(pam_use_sess))}, init([Srv, Act, Sess]); init([undefined, _Act, _Sess]) -> error_logger:format("pam: need service in pam environment\n", []), {stop, noservice}; init([SRV, Act, Sess]) -> %% we never want to use the accounting %% in yaws M1 = case Act of undefined -> ""; true -> "A"; false -> [] end, %% and we definitely never want to use the %% the session capability in yaws since noone is never %% ever going to close the session M2 = case Sess of undefined -> ""; true -> "S"; false -> [] end, Mode = M1 ++ M2, %% we're not starting the portprogram now, it's done %% on demand. {ok, #state{i = 0, mode = Mode, srv = SRV, port = undefined, sids = [], reqs = []}}. okundef({ok,Val}) -> Val; okundef(undefined) -> undefined. %%-------------------------------------------------------------------- %% Function: handle_call/3 %% Description: Handling call messages %% Returns: {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- handle_call({auth, User, Password}, From, State0) -> State = ensure_port(State0), I = integer_to_list(State#state.i), port_command(State#state.port, [$a, User, 0, Password, 0, State#state.mode,0, I, 0]), Ref = erlang:monitor(process, element(1, From)), U = #user{i = State#state.i, ref = Ref, from = From}, R = [U| State#state.reqs], {noreply, State#state{i = State#state.i + 1, reqs = R}, ?TO}; handle_call({close, _Sid}, _From, State = #state{port=undefined}) -> {reply, ok, State}; handle_call({close, Sid}, _From, State = #state{port = Port}) -> case lists:keysearch(Sid, #user.i, State#state.sids) of {value, U} -> erlang:demonitor(U#user.ref); false -> ok end, port_command(Port, [$c, integer_to_list(Sid), 0]), {reply, ok, State#state{ sids = lists:keydelete(Sid, #user.i, State#state.sids)},?TO}. %%-------------------------------------------------------------------- %% Function: handle_cast/2 %% Description: Handling cast messages %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State, ?TO}. %%-------------------------------------------------------------------- %% Function: handle_info/2 %% Description: Handling all non call/cast messages %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- handle_info(timeout, State) when State#state.port /= undefined, State#state.sids == [], State#state.reqs == [] -> unlink(State#state.port), port_close(State#state.port), {noreply, State#state{port = undefined}}; handle_info(timeout, State) -> {noreply, State, ?TO}; handle_info({'EXIT', Port, _}, State = #state{port = Port}) -> error_logger:format("epam port program died \n",[]), lists:foreach( fun(U) -> gen_server:reply(U#user.from, {no, "epam died"}) end, State#state.reqs), {noreply, State#state{sids = [], reqs = [], port = undefined }}; handle_info({'DOWN', MonitorRef, _Type, _Object, _Info}, State) when State#state.port /= undefined -> case lists:keysearch(MonitorRef, #user.ref, State#state.sids) of {value, U} -> port_command(State#state.port, [$c, integer_to_list(U#user.i), 0]), S2 = lists:keydelete(MonitorRef, #user.ref, State#state.sids), {noreply, State#state{sids = S2}, ?TO}; false -> {noreply, State, ?TO} end; handle_info({'DOWN', _MonitorRef, _Type, _Object, _Info}, State) -> {noreply, State}; handle_info({_Port, {data, Str}}, State) -> case string:tokens(Str, " \n") of ["pam", IntStr | Reply] -> I = list_to_integer(IntStr), {value, U} = lists:keysearch(I, #user.i, State#state.reqs), R = case reply(U#user.from, I, Reply) of yes -> [U |State#state.sids]; no -> State#state.sids end, {noreply, State#state{reqs = lists:keydelete(I,#user.i,State#state.reqs), sids = R}, ?TO}; _Other -> error_logger:format("epam: ~s", [Str]), {noreply, State, ?TO} end. %%-------------------------------------------------------------------- %% Function: terminate/2 %% Description: Shutdown the server %% Returns: any (ignored by gen_server) %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change/3 %% Purpose: Convert process state when code is changed %% Returns: {ok, NewState} %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- reply(From, Sid, ["yes"]) -> gen_server:reply(From, {yes, Sid}), yes; reply(From, _Sid, ["no", What |Reason ]) -> gen_server:reply(From, {no, {What, fsp(Reason)}}), no. fsp([]) -> []; fsp([X]) -> X; fsp([H|T]) -> H ++ " " ++ fsp(T). ensure_port(S = #state{port = undefined, srv = Srv}) -> Prg0 = filename:dirname(code:which(?MODULE)) ++ "/../priv/epam ", Prg = Prg0 ++ Srv, P = open_port({spawn, Prg}, [{packet, 2}]), receive {P, {data, "ok"}} -> S#state{port = P}; {P, {data, ErrStr}} -> error_logger:format("epam: ~s~n", [ErrStr]), exit(noepam); {'EXIT', P, _} -> error_logger:format("yaws_pam: Cannot start epam",[]), exit(noepam) end; ensure_port(S)-> S. yaws-2.0.2/src/yaws_exhtml.erl0000664000175000017500000002314012605311412013253 00000000000000%% -*- coding: Latin-1 -*- %%%---------------------------------------------------------------------- %%% File : exhtml.erl %%% Author : Joakim Grebenö %%% Purpose : Format ehtml as xhtml code with optional indentation support. %%% Created : 24 Apr 2006 by Joakim Grebenö %%%---------------------------------------------------------------------- -module(yaws_exhtml). -export([check_xhtml/1]). -export([fformat/0, sformat/0]). % test -export([format/1, format/2, format/3]). -export([sformat/1, sformat/2]). -export([count_trailing_spaces/1]). -define(INDENT_LEVEL, 2). fformat() -> % test HTML = format( [{table, [{tr, [{td, ["foo ", {em, ["bar"]}, " now.", {hr}, {p, "foo"}]}]}, {tr, [{td, ["foo ", {em, ["bar"]}, " now."]}]}]}]), io:format("~s~n", [lists:flatten(HTML)]). sformat() -> % test HTML = sformat( [{table, [{tr, [{td, ["foo ", {em, ["bar"]}, " now.", {hr}, {p, "foo"}]}]}, {tr, [{td, ["foo ", {em, ["bar"]}, " now."]}]}]}]), io:format("~s~n", [lists:flatten(HTML)]). check_xhtml(XHTMLContent) when is_list(XHTMLContent) -> check_xhtml(list_to_binary(XHTMLContent)); check_xhtml(XHTMLContent) when is_binary(XHTMLContent) -> {ok, Filename} = yaws:mktemp("confd"), ok = file:write_file(Filename, XHTMLContent), DTD = filename:join(code:priv_dir(webgui), "xhtml1-strict.dtd"), Cmd = "xmllint --dtdvalid "++DTD++" -noout -nonet "++Filename++" 2>&1", case os:cmd(Cmd) of "" -> file:delete(Filename), ok; Reason -> file:delete(Filename), {error, Reason} end. format(Data) -> tl(format(block, Data, fun value2string/1, 0, [])). format(Data, N) -> tl(format(block, Data, fun value2string/1, N, lists:duplicate(N, $ ))). format(Data, N, Value2StringF) -> tl(format(block, Data, Value2StringF, N, lists:duplicate(N, $ ))). format(Mode, Data, Value2StringF, N, Indent) when is_tuple(Data) -> format(Mode, [Data], Value2StringF, N, Indent); format(_Mode, [], _Value2StringF, _N, _Indent) -> []; format(Mode, [{'$html', HTML}|Rest], Value2StringF, N, Indent) -> [HTML|format(Mode, Rest, Value2StringF, N, Indent)]; format(Mode, [{Tag}|Rest], Value2StringF, N, Indent) -> format(Mode, [{Tag, [], []}|Rest], Value2StringF, N, Indent); format(Mode, [{Tag, Attrs}|Rest], Value2StringF, N, Indent) -> format(Mode, [{Tag, Attrs, []}|Rest], Value2StringF, N, Indent); format(Mode, [{Tag, Attrs, Body}|Rest], Value2StringF, N, Indent) -> TagString = lowercase(tag_string(Tag)), case {Mode, block_level(TagString), Body} of {first_in_block, no, []} -> [$\n, Indent, $<, TagString, format_attrs(Value2StringF, Attrs), $>, $<, $/, TagString, $>|format(Mode, Rest, Value2StringF, N, Indent)]; {block, no, []} -> [$<, TagString, format_attrs(Value2StringF, Attrs), $>, $<, $/, TagString, $>|format(Mode, Rest, Value2StringF, N, Indent)]; {first_in_block, yes, _} -> NextLevel = lists:duplicate(?INDENT_LEVEL, $ ), [$\n, Indent, $<, TagString, format_attrs(Value2StringF, Attrs), $>, format(first_in_block, Body, Value2StringF, N+?INDENT_LEVEL, [NextLevel, Indent]), $\n, Indent, $<, $/, TagString, $>| format(block, Rest, Value2StringF, N, Indent)]; %% Block element in a block element. {block, yes, _} -> NextLevel = lists:duplicate(?INDENT_LEVEL, $ ), [$\n, Indent, $<, TagString, format_attrs(Value2StringF, Attrs), $>, format(first_in_block, Body, Value2StringF, N+?INDENT_LEVEL, [NextLevel, Indent]), $\n, Indent, $<, $/, TagString, $>| format(block, Rest, Value2StringF, N, Indent)]; %% Inline element first in a block element. {first_in_block, no, _} -> [$\n, Indent, $<, TagString, format_attrs(Value2StringF, Attrs), $>, format(inline, Body, Value2StringF, N, Indent), $<, $/, TagString, $>| format(block, Rest, Value2StringF, N, Indent)]; %% Inline element in a block or an inline element. {_, no, _} -> [$<, TagString, format_attrs(Value2StringF, Attrs), $>, format(inline, Body, Value2StringF, N, Indent), $<, $/, TagString, $>| format(Mode, Rest, Value2StringF, N, Indent)] end; %% Inline data first in a block element. format(first_in_block, [String|Rest], Value2StringF, N, Indent) when is_list(String) -> [$\n, Indent, String|format(block, Rest, Value2StringF, N, Indent)]; %% Inline data in a block/inline element. format(Mode, [String|Rest], Value2StringF, N, Indent) when is_list(String) -> [String|format(Mode, Rest, Value2StringF, N, Indent)]; %% PCDATA in first a block element. format(first_in_block, Value, Value2StringF, _N, Indent) -> [$\n, Indent, Value2StringF(Value)]; %% PCDATA in a block element. format(block, Value, Value2StringF, _N, _Indent) -> [Value2StringF(Value)]; %% PCDATA in an inline element. format(inline, Value, Value2StringF, _N, _Indent) -> Value2StringF(Value). tag_string(TagAtom) when is_atom(TagAtom) -> atom_to_list(TagAtom); tag_string(TagString) -> TagString. lowercase(String) -> lowercase(String, []). lowercase([C|Cs], Acc) when C >= $A, C =< $Z -> lowercase(Cs, [C+($a-$A)| Acc]); lowercase([C|Cs], Acc) -> lowercase(Cs, [C| Acc]); lowercase([], Acc) -> lists:reverse(Acc). %% The following are defined as block-level elements: block_level("address") -> yes; block_level("blockquote") -> yes; block_level("center") -> yes; block_level("dir") -> yes; block_level("div") -> yes; block_level("dl") -> yes; block_level("fieldset") -> yes; block_level("form") -> yes; block_level("h1") -> yes; block_level("h2") -> yes; block_level("h3") -> yes; block_level("h4") -> yes; block_level("h5") -> yes; block_level("h6") -> yes; block_level("hr") -> yes; block_level("input") -> yes; block_level("isindex") -> yes; block_level("menu") -> yes; block_level("noframes") -> yes; block_level("noscript") -> yes; block_level("ol") -> yes; block_level("p") -> yes; block_level("pre") -> yes; block_level("table") -> yes; block_level("textarea") -> no; block_level("tbody") -> yes; block_level("ul") -> yes; block_level("select") -> yes; %% The following elements may also be considered block-level elements since %% they may contain block-level elements: block_level("dd") -> yes; block_level("dt") -> yes; block_level("frameset") -> yes; block_level("li") -> yes; block_level("td") -> yes; block_level("tfoot") -> yes; block_level("th") -> yes; block_level("thead") -> yes; block_level("tr") -> yes; %% The following elements may be used as either block-level elements or %% inline elements. If used as inline elements (e.g., within another inline %% element or a P), these elements should not contain any block-level %% elements. block_level("applet") -> yes; block_level("button") -> yes; block_level("del") -> yes; block_level("iframe") -> yes; block_level("ins") -> yes; block_level("map") -> yes; block_level("object") -> yes; block_level("script") -> yes; %% All else are defined as inline elements: block_level(_) -> no. format_attrs(_Value2StringF, []) -> []; format_attrs(Value2StringF, [{Name, Value}|Rest]) -> [$ , lowercase(tag_string(Name)), $=, $\", Value2StringF(Value), $\"| format_attrs(Value2StringF, Rest)]. value2string(Atom) when is_atom(Atom) -> atom_to_list(Atom); value2string(Integer) when is_integer(Integer) -> integer_to_list(Integer); value2string(Float) when is_float(Float) -> float_to_list(Float); value2string(Binary) when is_binary(Binary) -> Binary; value2string(String) when is_list(String) -> String. sformat(Data) -> sformat(Data, fun value2string/1). sformat(Data, Value2StringF) when is_tuple(Data) -> sformat([Data], Value2StringF); sformat([], _Value2StringF) -> []; sformat([{Tag}|Rest], Value2StringF) -> sformat([{Tag, [], []}|Rest], Value2StringF); sformat([{Tag, Body}|Rest], Value2StringF) -> sformat([{Tag, [], Body}|Rest], Value2StringF); sformat([{Tag, Attrs, []}|Rest], Value2StringF) -> TagString = lowercase(tag_string(Tag)), [$<, TagString, format_attrs(Value2StringF, Attrs), $/, $>| sformat(Rest, Value2StringF)]; sformat([{Tag, Attrs, Body}|Rest], Value2StringF) -> TagString = lowercase(tag_string(Tag)), [$<, TagString, format_attrs(Value2StringF, Attrs), $>, sformat(Body, Value2StringF), $<, $/, TagString, $>| sformat(Rest, Value2StringF)]; sformat([String|Rest], Value2StringF) when is_list(String) -> [String|sformat(Rest, Value2StringF)]; sformat(Value, Value2StringF) -> Value2StringF(Value). -define(SZ, 16). count_trailing_spaces(<<>>) -> 0; count_trailing_spaces(Bin) -> count_trailing_spaces(Bin, size(Bin), 0). count_trailing_spaces(Bin, Stop, N) -> Start = if Stop =< ?SZ -> 1; true -> Stop - ?SZ + 1 end, L = binary_to_list(Bin, Start, Stop), case spaces_in_list(L) of ?SZ when Start == 1 -> N + ?SZ; ?SZ -> %% keep going count_trailing_spaces(Bin, Start-1, N + ?SZ); M -> N + M end. spaces_in_list(L) -> spaces_in_list(lists:reverse(L), 0). spaces_in_list([$\s | T], N) -> spaces_in_list(T, N+1); spaces_in_list(_, N) -> N. yaws-2.0.2/src/yaws_rpc.erl0000664000175000017500000004632712605311412012552 00000000000000%% -*- coding: Latin-1 -*- %% Copyright (C) 2003 Joakim Grebenö . %% All rights reserved. %% %% Copyright (C) 2006 Gaspar Chilingarov %% Gurgen Tumanyan %% All rights reserved. %% %% %% Redistribution and use in source and binary forms, with or without %% modification, are permitted provided that the following conditions %% are met: %% %% 1. Redistributions of source code must retain the above copyright %% notice, this list of conditions and the following disclaimer. %% 2. Redistributions in binary form must reproduce the above %% copyright notice, this list of conditions and the following %% disclaimer in the documentation and/or other materials provided %% with the distribution. %% %% THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS %% OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED %% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE %% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY %% DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL %% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE %% GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS %% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, %% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING %% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS %% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %% NOTE: This module was originally called yaws_jsonrpc. %% It was hacked to transparently supports haXe remoting as well, %% hence its name was changed to the more generic 'yaws_rpc'. %% %% modified by Yariv Sadan (yarivvv@gmail.com) -module(yaws_rpc). -author("Gaspar Chilingarov , Gurgen Tumanyan "). -modified_by("Yariv Sadan "). -modified_by("Steve Vinoski "). -export([handler/2]). -export([handler_session/2, handler_session/3]). %%-define(debug, 1). -include("yaws_debug.hrl"). -include("../include/yaws_api.hrl"). %%% ###################################################################### %%% public interface %%% %%% %%% use rpc handler which can automagically start sessions if we need %%% handler_session(Args, Handler) -> handler_session(Args, Handler, 'SID'). %%% %%% allow overriding session Cookie name %%% handler_session(Args, Handler, SID_NAME) when is_atom(SID_NAME) -> handler_session(Args, Handler, atom_to_list(SID_NAME)); handler_session(Args, Handler, SID_NAME) -> handler(Args, Handler, {session, SID_NAME}). % go to generic handler %%% %%% xmlrpc:handler compatible call %%% no session support will be available handler(Args, Handler) -> handler(Args, Handler, simple). %%% ###################################################################### %%% private functions %%% %%% we should be called from yaws page or module handler(Args, Handler, Type) when is_record(Args, arg) -> case parse_request(Args) of ok -> handle_payload(Args, Handler, Type); {status, StatusCode} -> % cannot parse request send(Args, StatusCode) end. -define(ERROR_LOG(Reason), error_logger:error_report({?MODULE, ?LINE, Reason})). -define(LOG(Reason), ?ERROR_LOG(Reason)). %%% %%% check that request come in reasonable protocol version and reasonable method %%% parse_request(Args) -> Req = Args#arg.req, case {Req#http_request.method, Req#http_request.version} of {'POST', {1,0}} -> ?Debug("HTTP Version 1.0~n", []), ok; {'POST', {1,1}} -> ?Debug("HTTP Version 1.1~n", []), ok; {'POST', _HTTPVersion} -> {status, 505}; {_Method, {1,1}} -> {status, 501}; _ -> {status, 400} end. handle_payload(Args, Handler, Type) -> RpcType = recognize_rpc_type(Args), %% haXe parameters are URL encoded PL = unicode:characters_to_list(Args#arg.clidata), {Payload,DecodedStr} = case RpcType of T when T==haxe; T==json -> ?Debug("rpc ~p call ~p~n", [T, PL]), {PL, yaws_api:url_decode(PL)}; soap_dime -> [{_,_,_,Req}|As] = yaws_dime:decode(Args#arg.clidata), {Args#arg.clidata, {binary_to_list(Req), As}}; _ -> ?Debug("rpc plaintext call ~p~n", [PL]), {PL, PL} end, case decode_handler_payload(RpcType, DecodedStr) of Batch when RpcType == json, is_list(Batch) -> BatchRes = lists:foldl( fun(Req, Acc) -> Result = check_decoded_payload(Args, Handler, Req, Payload, Type, json), case Result of empty -> Acc; {result, _Code, Send} -> [Send|Acc]; {send, S} -> %% TODO: it would be better if %% Result was never of the %% {send, ...} variety because %% it requires us to take the %% content out via searching. case lists:keysearch(content,1,S) of {value, {content, _, Send}} -> [Send|Acc]; _ -> Acc end end end, [], Batch), case BatchRes of [] -> %% all notifications, no replies send(Args, 200, json); _ -> send(Args, 200, "["++yaws:join_sep(lists:reverse(BatchRes),",")++"]", [], json) end; NonBatch -> Result = check_decoded_payload(Args, Handler, NonBatch, Payload, Type, RpcType), case Result of {send, Send} -> Send; empty -> send(Args, 200, RpcType); {result, Code, Send} -> send(Args, Code, Send, [], RpcType) end end. check_decoded_payload(Args, Handler, DecodedResult, Payload, Type, RpcType) -> case DecodedResult of {ok, DecodedPayload, ID} -> ?Debug("client2erl decoded call ~p~n", [DecodedPayload]), eval_payload(Args, Handler, DecodedPayload, Type, ID, RpcType); {error, Reason} -> ?ERROR_LOG({html, client2erl, Payload, Reason}), case RpcType of json -> case Reason of {ErrCode, _ErrString} -> {result, 200, json_error(ErrCode)}; ErrCode -> {result, 200, json_error(ErrCode)} end; _ -> {send, send(Args, 400, RpcType)} end end. %%% Identify the RPC type. We first try to recognize haXe by the %%% "X-Haxe-Remoting" HTTP header, then the "SOAPAction" header, %%% and if those are absent we assume the request is JSON. recognize_rpc_type(Args) -> case (Args#arg.headers)#headers.content_type of "application/dime" -> soap_dime; _ -> OtherHeaders = ((Args#arg.headers)#headers.other), recognize_rpc_hdr([{X,Y,yaws:to_lower(Z),Q,W} || {X,Y,Z,Q,W} <- OtherHeaders]) end. recognize_rpc_hdr([{_,_,"x-haxe-remoting",_,_}|_]) -> haxe; recognize_rpc_hdr([{_,_,"soapaction",_,_}|_]) -> soap; recognize_rpc_hdr([_|T]) -> recognize_rpc_hdr(T); recognize_rpc_hdr([]) -> json. %%% %%% call handler/3 and provide session support eval_payload(Args, {M, F}, Payload, {session, CookieName}, ID, RpcType) -> {SessionValue, Cookie} = case yaws_api:find_cookie_val(CookieName, (Args#arg.headers)#headers.cookie) of [] -> %% have no session started, just call handler {undefined, undefined}; Cookie2 -> %% get old session data case yaws_api:cookieval_to_opaque(Cookie2) of {ok, OP} -> {OP, Cookie2}; {error, _ErrMsg} -> % cannot get corresponding session {undefined, undefined} end end, CbackFun = callback_fun(M, F, Args, Payload, SessionValue, RpcType), case catch CbackFun() of {'EXIT', {function_clause, _}} when RpcType == json -> case ID of undefined -> %% empty HTTP reply for notification empty; _ -> {result, 200, json_error(-32601, ID)} end; {'EXIT', Reason} -> ?ERROR_LOG({M, F, {'EXIT', Reason}}), {send, send(Args, 500, RpcType)}; {error, Reason} -> ?ERROR_LOG({M, F, Reason}), {send, send(Args, 500, RpcType)}; {error, Reason, Rc} -> ?ERROR_LOG({M, F, Reason}), {send, send(Args, Rc, Reason, [], RpcType)}; {false, ResponsePayload} -> %% do not have updates in session data {send, encode_send(Args, 200, ResponsePayload, [], ID, RpcType)}; {false, ResponsePayload, RespCode} -> %% do not have updates in session data {send, encode_send(Args,RespCode,ResponsePayload,[],ID,RpcType)}; false -> % soap or json-rpc notify empty; {true, _NewTimeout, NewSessionValue, ResponsePayload} -> %% be compatible with xmlrpc module CO = handle_cookie(Cookie, CookieName, SessionValue, NewSessionValue, M, F), {send, encode_send(Args, 200, ResponsePayload, CO, ID, RpcType)}; {true, _NewTimeout, NewSessionValue, ResponsePayload, RespCode} -> %% be compatible with xmlrpc module CO = handle_cookie(Cookie, CookieName, SessionValue, NewSessionValue, M, F), {send, encode_send(Args, RespCode, ResponsePayload, CO, ID, RpcType)} end; %%% %%% call handler/2 without session support %%% eval_payload(Args, {M, F}, Payload, simple, ID, RpcType) -> case catch M:F(Args#arg.state, Payload) of {'EXIT', Reason} -> ?ERROR_LOG({M, F, {'EXIT', Reason}}), {send, send(Args, 500)}; {error, Reason} -> ?ERROR_LOG({M, F, Reason}), {send, send(Args, 500)}; {false, ResponsePayload} -> {send, encode_send(Args, 200, ResponsePayload, [], ID, RpcType)}; false -> % Soap notify {send, send(Args, 200, RpcType)}; {true, _NewTimeout, _NewState, ResponsePayload} -> {send, encode_send(Args, 200, ResponsePayload, [], ID, RpcType)} end. handle_cookie(Cookie, CookieName, SessionValue, NewSessionValue, M, F) -> case NewSessionValue of undefined when Cookie == undefined -> []; % nothing to do undefined -> % rpc handler requested session delete yaws_api:delete_cookie_session(Cookie), []; %% XXX: may be return set-cookie with empty val? _ -> %% any other value will stored in session case SessionValue of undefined -> %% got session data and should start new session now Cookie1 = yaws_api:new_cookie_session(NewSessionValue), case get_expire(M, F) of false -> yaws_api:setcookie(CookieName, Cookie1, "/"); %% return set_cookie header Expire -> yaws_api:setcookie(CookieName, Cookie1, "/",Expire) %% return set_cookie header end; _ -> yaws_api:replace_cookie_session(Cookie, NewSessionValue), [] % nothing to add to yaws data end end. %%% Make it possible for callback module to set Cookie Expire string! get_expire(M, F) -> case catch M:F(cookie_expire) of Expire when is_list(Expire) -> Expire; _ -> false end. callback_fun(M, F, Args, Payload, SessionValue, RpcType) when RpcType =:= soap; RpcType =:= soap_dime -> fun() -> yaws_soap_srv:handler(Args, {M,F}, Payload, SessionValue) end; callback_fun(M, F, Args, Payload, SessionValue, _RpcType) -> fun() -> M:F(Args#arg.state, Payload, SessionValue) end. %%% XXX compatibility with XMLRPC handlers %%% XXX - potential bug here? encode_send(Args, StatusCode, [Payload], AddOn, ID, RpcType) -> encode_send(Args, StatusCode, Payload, AddOn, ID, RpcType); encode_send(Args, StatusCode, Payload, AddOn, ID, RpcType) -> ?Debug("rpc response ~p ~n", [Payload]), case encode_handler_payload(Payload, ID, RpcType) of {ok, EncodedPayload, NewRpcType} -> ?Debug("rpc encoded response ~p ~n", [EncodedPayload]), send(Args, StatusCode, EncodedPayload, AddOn, NewRpcType); {ok, EncodedPayload} -> ?Debug("rpc encoded response ~p ~n", [EncodedPayload]), send(Args, StatusCode, EncodedPayload, AddOn, RpcType) end. send(Args, StatusCode) -> send(Args, StatusCode, json). send(Args, StatusCode, RpcType) -> send(Args, StatusCode, "", [], RpcType). send(Args, StatusCode, Payload, AddOn, RpcType) when not is_list(AddOn) -> send(Args, StatusCode, Payload, [AddOn], RpcType); send(Args, StatusCode, Payload, AddOnData, RpcType) -> [{status, StatusCode}, content_hdr(RpcType, Args, Payload), {header, {content_length, lists:flatlength(Payload)}}] ++ AddOnData. content_hdr(json, _Args, Payload) -> {content, "application/json", Payload}; content_hdr(soap, Args, Payload) -> CallerContentType = (Args#arg.headers)#headers.content_type, %% drop caller charset info if present, may not %% be appropriate for the response ContentType = hd(string:tokens(CallerContentType, ";")), {content, ContentType, Payload}; content_hdr(_, _Args, Payload) -> {content, "text/xml", Payload}. encode_handler_payload({Xml,[]}, _ID, soap_dime) -> {ok, Xml, soap}; encode_handler_payload({Xml,As}, _ID, soap_dime) -> EncodedPayload = yaws_dime:encode(Xml, As), {ok, EncodedPayload}; encode_handler_payload(Xml, _ID, soap_dime) -> {ok, Xml, soap}; encode_handler_payload({Xml,[]}, _ID, soap) -> {ok, Xml}; encode_handler_payload({Xml,As}, _ID, soap) -> EncodedPayload = yaws_dime:encode(Xml, As), {ok, EncodedPayload, soap_dime}; encode_handler_payload(Xml, _ID, soap) -> {ok, Xml}; encode_handler_payload({error, [ErlStruct]}, ID, RpcType) -> encode_handler_payload({error, ErlStruct}, ID, RpcType); encode_handler_payload({error, ErlStruct}, ID, RpcType) -> StructStr = case RpcType of json -> json2:encode({struct, [{id, ID}, {error, ErlStruct}, {"jsonrpc", "2.0"}]}); haxe -> [$h, $x, $r | haxe:encode({exception, ErlStruct})] end, {ok, StructStr}; encode_handler_payload({response, [ErlStruct]}, ID, RpcType) -> encode_handler_payload({response, ErlStruct}, ID, RpcType); encode_handler_payload({response, ErlStruct}, ID, RpcType) -> StructStr = case RpcType of json -> json2:encode({struct, [{result, ErlStruct}, {id, ID}, {"jsonrpc", "2.0"}]}); haxe -> [$h, $x, $r | haxe:encode(ErlStruct)] end, {ok, StructStr}. decode_handler_payload(json, JSonStr) -> try {ok, Obj} = json2:decode_string(JSonStr), decode_handler_payload_json(Obj) catch error:Err -> ?ERROR_LOG({json_decode, JSonStr, Err}), {error, {-32700, Err}} end; decode_handler_payload(haxe, [$_, $_, $x, $= | HaxeStr]) -> try {done, {ok, {array, [MethodName | _]}}, Cont} = haxe:decode(HaxeStr), {done, {ok, Args}, _Cont2} = haxe:decode_next(Cont), %% ID is undefined because haXe remoting doesn't automagically handle %% sessions. {ok, {call, list_to_atom(MethodName), Args}, undefined} catch error:Err -> {error, Err} end; decode_handler_payload(haxe, _HaxeStr) -> {error, missing_haxe_prefix}; decode_handler_payload(soap_dime, Payload) -> {ok, Payload, undefined}; decode_handler_payload(soap, Payload) -> {ok, Payload, undefined}. decode_handler_payload_json({struct, _}=Obj) -> case jsonrpc:s(Obj, method) of undefined -> {error, -32600}; Method0 when is_list(Method0) -> Method = case jsonrpc:s(Obj, jsonrpc) of "2.0" -> try list_to_existing_atom(Method0) catch error:badarg -> Method0 end; undefined -> list_to_atom(Method0) end, Args = jsonrpc:s(Obj, params), ArgsOk = case Args of {struct, _} -> true; {array, _} -> true; undefined -> true; _ -> false end, case ArgsOk of true -> ID = jsonrpc:s(Obj, id), CallOrNotify = case ID of undefined -> notification; _ -> call end, {ok, {CallOrNotify, Method, Args}, ID}; false -> {error, -32602} end; _ -> {error, -32600} end; decode_handler_payload_json({array, []}) -> {error, -32600}; decode_handler_payload_json({array, Batch}) -> [decode_handler_payload_json(Obj) || Obj <- Batch]; decode_handler_payload_json(_) -> {error, -32600}. json_error(ErrCode) -> json_error(ErrCode, null). json_error(ErrCode, Id) -> Err = {struct, [{"jsonrpc", "2.0"}, {"id", Id}, {"error", {struct, [{"code", ErrCode}, {"message", json_error_message(ErrCode)}]}}]}, json2:encode(Err). json_error_message(-32700) -> "parse error"; json_error_message(-32600) -> "invalid request"; json_error_message(-32601) -> "method not found"; json_error_message(-32602) -> "invalid params"; json_error_message(-32603) -> "internal error"; json_error_message(Code) when Code >= -32099, Code =< -32000 -> "server error"; json_error_message(_) -> "json error". yaws-2.0.2/src/yaws_soap_srv.erl0000664000175000017500000002557612605311412013625 00000000000000%%%------------------------------------------------------------------- %%% Created : 29 Nov 2006 by Torbjorn Tornkvist %%% Author : Willem de Jong (w.a.de.jong@gmail.com). %%% Desc : A SOAP server. %%%------------------------------------------------------------------- -module(yaws_soap_srv). -behaviour(gen_server). %% API -export([start_link/0, start_link/1, setup/1, setup/2, setup/3, handler/4 ]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("../include/yaws_api.hrl"). -include("../include/yaws.hrl"). -include("../include/soap.hrl"). -define(SERVER, ?MODULE). %% State -record(s, { wsdl_list = [] % list of {Id, WsdlModel} tuples, where Id == {M,F} }). -define(OK_CODE, 200). -define(BAD_MESSAGE_CODE, 400). %% -define(METHOD_NOT_ALLOWED_CODE, 405). -define(SERVER_ERROR_CODE, 500). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link() -> start_link([]). start_link(L) -> %% We are dependent on erlsom case code:ensure_loaded(erlsom) of {error, _} -> Emsg = "could not load erlsom", error_logger:error_msg("~p: exiting, reason: ~s~n", [?MODULE, Emsg]), {error, Emsg}; {module, erlsom} -> gen_server:start_link({local, ?SERVER}, ?MODULE, L, []) end. %%% To be called from yaws_rpc.erl %%% Return according to yaws_rpc:eval_payload/6 handler(Args, Id, Payload, SessionValue) -> Headers = Args#arg.headers, SoapAction = yaws_soap_lib:findHeader("SOAPAction", Headers#headers.other), case gen_server:call(?SERVER, {request, Id, Payload, SessionValue, SoapAction}, infinity) of {ok, XmlDoc, ResCode, undefined} -> {false, XmlDoc, ResCode}; {ok, XmlDoc, ResCode, SessVal} -> {true, 0, SessVal, XmlDoc, ResCode}; {error, _, _} = Error -> Error; false -> false % soap notify end. %% Setup a SOAP interface according to the config file. setup(_ConfigFile) -> tbd. setup(Id, WsdlFile) when is_tuple(Id),size(Id)==2 -> Wsdl = yaws_soap_lib:initModel(WsdlFile), gen_server:call(?SERVER, {add_wsdl, Id, Wsdl}, infinity). %% PrefixOrOptions can be either a prefix (a String) or a property %% list. It is used to construct the options that are passed to Erlsom %% to compile the WSDL file. Passing a string ("Prefix") is equivalent %% to [{prefix, "Prefix"}]. %% If a list of erlsom options is passed, and this does not contain %% the {prefix, ...} option, the yaws_soap default ("p") will be used. setup(Id, WsdlFile, PrefixOrOptions) when is_tuple(Id),size(Id)==2 -> Wsdl = yaws_soap_lib:initModel(WsdlFile, PrefixOrOptions), gen_server:call(?SERVER, {add_wsdl, Id, Wsdl}, infinity). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init(L) -> %% [ {{Mod,Handler}, WsdlFile} ] WsdlList = lists:foldl( fun( SoapSrvMod, OldList) -> setup_on_init( SoapSrvMod, OldList ) end,[],L), {ok, #s{wsdl_list = WsdlList}}. setup_on_init( {Id, WsdlFile}, OldList ) when is_tuple(Id),size(Id) == 2 -> Wsdl = yaws_soap_lib:initModel(WsdlFile), uinsert({Id, Wsdl}, OldList); setup_on_init( {Id, WsdlFile, Prefix}, OldList ) when is_tuple(Id), size(Id) == 2 -> Wsdl = yaws_soap_lib:initModel(WsdlFile, Prefix), uinsert({Id, Wsdl}, OldList). %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call({add_wsdl, Id, WsdlModel}, _From, State) -> NewWsdlList = uinsert({Id, WsdlModel}, State#s.wsdl_list), {reply, ok, State#s{wsdl_list = NewWsdlList}}; %% handle_call( {request, Id, Payload, SessionValue, SoapAction}, _From, State) -> Reply = request(State, Id, Payload, SessionValue, SoapAction), {reply, Reply, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- request(State, {M,F} = Id, {Req, Attachments}, SessionValue, Action) -> {ok, Model} = get_model(State, Id), %%error_logger:info_report([?MODULE, {payload, Req}]), case catch yaws_soap_lib:parseMessage(Req, Model) of {ok, Header, Body} -> %% call function result(Model, catch apply(M, F, [Header, Body, Action, SessionValue, Attachments])); {error, Error} -> cli_error(Error); OtherError -> srv_error(io_lib:format("Error parsing message: ~p", [OtherError])) end; request(State, {M,F} = Id, Req, SessionValue, Action) -> %%error_logger:info_report([?MODULE, {payload, Req}]), {ok, Model} = get_model(State, Id), Umsg = (catch erlsom_lib:toUnicode(Req)), case catch yaws_soap_lib:parseMessage(Umsg, Model) of {ok, Header, Body} -> %% call function result(Model, catch apply(M, F, [Header, Body, Action, SessionValue])); {error, Error} -> cli_error(Error); OtherError -> srv_error(io_lib:format("Error parsing message: ~p", [OtherError])) end. %%% Analyse the result and produce some output result(Model, {ok, ResHeader, ResBody, ResCode, SessVal}) -> return(Model, ResHeader, ResBody, ResCode, SessVal, undefined); result(Model, {ok, ResHeader, ResBody}) -> return(Model, ResHeader, ResBody, ?OK_CODE, undefined, undefined); result(Model, {ok, ResHeader, ResBody, Files}) -> return(Model, ResHeader, ResBody, ?OK_CODE, undefined, Files); result(_Model, {error, client, ClientMssg}) -> cli_error(ClientMssg); result(_Model, false) -> % soap notify ! false; result(_Model, Error) -> srv_error(io_lib:format("Error processing message: ~p", [Error])). return(#wsdl{model = Model}, ResHeader, ResBody, ResCode, SessVal, Files) -> return(Model, ResHeader, ResBody, ResCode, SessVal, Files); return(Model, ResHeader, ResBody, ResCode, SessVal, Files) when not is_list(ResBody) -> return(Model, ResHeader, [ResBody], ResCode, SessVal, Files); return(Model, ResHeader, ResBody, ResCode, SessVal, Files) -> %% add envelope Header2 = case ResHeader of undefined -> undefined; _ -> #'soap:Header'{choice = ResHeader} end, Envelope = #'soap:Envelope'{'Body' = #'soap:Body'{choice = ResBody}, 'Header' = Header2}, case catch erlsom:write(Envelope, Model) of {ok, XmlDoc} -> case Files of undefined -> {ok, XmlDoc, ResCode, SessVal}; _ -> DIME = yaws_dime:encode(XmlDoc, Files), {ok, DIME, ResCode, SessVal} end; {error, WriteError} -> srv_error(f("Error writing XML: ~p", [WriteError])); OtherWriteError -> error_logger:error_msg("~p(~p): OtherWriteError=~p~n", [?MODULE, ?LINE, OtherWriteError]), srv_error(f("Error writing XML: ~p", [OtherWriteError])) end. f(S,A) -> lists:flatten(io_lib:format(S,A)). cli_error(Error) -> error_logger:error_msg("~p(~p): Cli Error: ~p~n", [?MODULE, ?LINE, Error]), Fault = yaws_soap_lib:makeFault("Client", "Client error"), {error, Fault, ?BAD_MESSAGE_CODE}. srv_error(Error) -> error_logger:error_msg("~p(~p): Srv Error: ~p~n", [?MODULE, ?LINE, Error]), Fault = yaws_soap_lib:makeFault("Server", "Server error"), {error, Fault, ?SERVER_ERROR_CODE}. get_model(State, Id) -> case lists:keysearch(Id, 1, State#s.wsdl_list) of {value, {_, Model}} -> {ok, Model}; _ -> {error, "model not found"} end. uinsert({K,_} = E, [{K,_}|T]) -> [E|T]; uinsert(E, [H|T]) -> [H|uinsert(E,T)]; uinsert(E, []) -> [E]. yaws-2.0.2/src/yaws_app.erl0000664000175000017500000000076612605311412012543 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_app.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 16 Jan 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws_app). -author('klacke@hyber.org'). -behaviour(application). -export([start/2,stop/1]). %% start start(_Type, _StartArgs) -> yaws_sup:start_link(). %% stop stop(_State) -> ok. yaws-2.0.2/src/yaws_soap_lib.erl0000664000175000017500000006726712605311412013564 00000000000000%%%------------------------------------------------------------------- %%% Created : 29 Nov 2006 by Torbjorn Tornkvist %%% Author : Willem de Jong (w.a.de.jong@gmail.com). %%% Desc. : Common SOAP code. %%%------------------------------------------------------------------- %%% modified (WdJ, May 2007): deal with imports in the WSDL. %%% modified (WdJ, August 2007): the WSDL can contain more than 1 schema -module(yaws_soap_lib). -export([initModel/1, initModel/2, initModelFile/1, config_file_xsd/0, call/3, call/4, call/5, call/6, call_attach/4, call_attach/5, call_attach/7, write_hrl/2, write_hrl/3, findHeader/2, parseMessage/2, makeFault/2, is_wsdl/1, wsdl_model/1, wsdl_op_service/1, wsdl_op_port/1, wsdl_op_operation/1, wsdl_op_binding/1, wsdl_op_address/1, wsdl_op_action/1, wsdl_operations/1, get_operation/2 ]). %%% For testing... -export([qtest/0]). -include("../include/soap.hrl"). -define(HTTP_REQ_TIMEOUT, 20000). %%-define(dbg(X,Y), %% error_logger:info_msg("*dbg ~p(~p): " X, %% [?MODULE, ?LINE | Y])). -define(dbg(X,Y), true). -record(yaws_soap_config, {atts, xsd_path, user_module, wsdl_file, add_files}). -record(xsd_file, {atts, name, prefix, import_specs}). -record(import_specs, {atts, namespace, prefix, location}). -define(DefaultPrefix, "p"). %%% %%% Writes the header file (record definitions) for a WSDL file %%% write_hrl(WsdlURL, Output) when is_list(WsdlURL) -> write_hrl(initModel(WsdlURL), Output); write_hrl(#wsdl{model = Model}, Output) when is_list(Output) -> erlsom:write_hrl(Model, Output). write_hrl(WsdlURL, Output, PrefixOrOptions) when is_list(WsdlURL),is_list(PrefixOrOptions) -> write_hrl(initModel(WsdlURL, PrefixOrOptions), Output). %%% For testing only... qtest() -> call("http://www.webservicex.net/WeatherForecast.asmx?WSDL", "GetWeatherByPlaceName", ["Boston"]). %%% -------------------------------------------------------------------- %%% Access functions %%% -------------------------------------------------------------------- is_wsdl(Wsdl) when is_record(Wsdl,wsdl) -> true; is_wsdl(_) -> false. wsdl_operations(#wsdl{operations = Ops}) -> Ops. wsdl_model(#wsdl{model = Model}) -> Model. wsdl_op_service(#operation{service = Service}) -> Service. wsdl_op_port(#operation{port = Port}) -> Port. wsdl_op_operation(#operation{operation = Op}) -> Op. wsdl_op_binding(#operation{binding = Binding}) -> Binding. wsdl_op_address(#operation{address = Address}) -> Address. wsdl_op_action(#operation{action = Action}) -> Action. %%% -------------------------------------------------------------------- %%% For Quick deployment %%% -------------------------------------------------------------------- call(WsdlURL, Operation, ListOfData) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, ?DefaultPrefix), call(Wsdl, Operation, ListOfData); call(Wsdl, Operation, ListOfData) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> Msg = mk_msg(?DefaultPrefix, Operation, ListOfData), call(Wsdl, Operation, Op#operation.port, Op#operation.service, [], Msg); Else -> Else end. %%% -------------------------------------------------------------------- %%% With additional specified prefix %%% -------------------------------------------------------------------- call(WsdlURL, Operation, ListOfData, prefix, Prefix) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, Prefix), call(Wsdl, Operation, ListOfData, prefix, Prefix ); call(Wsdl, Operation, ListOfData, prefix, Prefix) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> Msg = mk_msg(Prefix, Operation, ListOfData), call(Wsdl, Operation, Op#operation.port, Op#operation.service, [], Msg); Else -> Else end. %%% -------------------------------------------------------------------- %%% Takes the actual records for the Header and Body message. %%% -------------------------------------------------------------------- call(WsdlURL, Operation, Header, Msg) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, ?DefaultPrefix), call(Wsdl, Operation, Header, Msg); call(Wsdl, Operation, Header, Msg) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> call(Wsdl, Operation, Op#operation.port, Op#operation.service, Header, Msg); Else -> Else end. mk_msg(Prefix, Operation, ListOfData) -> list_to_tuple([list_to_atom(Prefix++":"++Operation), % record name [] % anyAttribs | ListOfData]). % rest of record data get_operation([#operation{operation = X} = Op|_], X) -> {ok, Op}; get_operation([_|T], Op) -> get_operation(T, Op); get_operation([], _Op) -> {error, "operation not found"}. %%% -------------------------------------------------------------------- %%% Make a SOAP request (no attachments) %%% -------------------------------------------------------------------- call(Wsdl, Operation, Port, Service, Headers, Message) -> call_attach(Wsdl, Operation, Port, Service, Headers, Message, []). %%% -------------------------------------------------------------------- %%% For Quick deployment (with attachments) %%% -------------------------------------------------------------------- call_attach(WsdlURL, Operation, ListOfData, Attachments) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, ?DefaultPrefix), call_attach(Wsdl, Operation, ListOfData, Attachments); call_attach(Wsdl, Operation, ListOfData, Attachments) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> Msg = mk_msg(?DefaultPrefix, Operation, ListOfData), call_attach(Wsdl, Operation, Op#operation.port, Op#operation.service, [], Msg, Attachments); Else -> Else end. %%% -------------------------------------------------------------------- %%% Takes the actual records for the Header and Body message %%% (with attachments) %%% -------------------------------------------------------------------- call_attach(WsdlURL, Operation, Header, Msg, Attachments) when is_list(WsdlURL) -> Wsdl = initModel(WsdlURL, ?DefaultPrefix), call_attach(Wsdl, Operation, Header, Msg, Attachments); call_attach(Wsdl, Operation, Header, Msg, Attachments) when is_record(Wsdl, wsdl) -> case get_operation(Wsdl#wsdl.operations, Operation) of {ok, Op} -> call_attach(Wsdl, Operation, Op#operation.port, Op#operation.service, Header, Msg, Attachments); Else -> Else end. %%% -------------------------------------------------------------------- %%% Make a SOAP request (with attachments) %%% -------------------------------------------------------------------- call_attach(#wsdl{operations = Operations, model = Model}, Operation, Port, Service, Headers, Message, Attachments) -> %% find the operation case findOperation(Operation, Port, Service, Operations) of #operation{address = URL, action = SoapAction} -> %% Add the Soap envelope Envelope = mk_envelope(Message, Headers), %% Encode the message case erlsom:write(Envelope, Model) of {ok, XmlMessage} -> {ContentType, Request} = make_request_body(XmlMessage, Attachments), HttpHeaders = [], HttpClientOptions = [], ?dbg("+++ Request = ~p~n", [Request]), HttpRes = http_request(URL, SoapAction, Request, HttpClientOptions, HttpHeaders, ContentType), ?dbg("+++ HttpRes = ~p~n", [HttpRes]), case HttpRes of {ok, _Code, _ReturnHeaders, Body} -> parseMessage(Body, Model); Error -> %% in case of HTTP error: return %% {error, description} Error end; {error, EncodingError} -> {error, {encoding_error, EncodingError}} end; false -> {error, {unknown_operation, Operation}} end. %%% %%% returns {ok, Header, Body} | {error, Error} %%% parseMessage(Message, #wsdl{model = Model}) -> parseMessage(Message, Model); %% parseMessage(Message, Model) -> case erlsom:scan(Message, Model) of {ok, #'soap:Envelope'{'Body' = #'soap:Body'{choice = Body}, 'Header' = undefined}, _} -> {ok, undefined, Body}; {ok, #'soap:Envelope'{'Body' = #'soap:Body'{choice = Body}, 'Header' = #'soap:Header'{choice = Header}}, _} -> {ok, Header, Body}; {error, ErrorMessage} -> {error, {decoding, Message, ErrorMessage}} end. findOperation(_Operation, _Port, _Service, []) -> false; findOperation(Operation, Port, Service, [Op = #operation{operation = Operation, port = Port, service = Service} | _]) -> Op; findOperation(Operation, Port, Service, [#operation{} | Tail]) -> findOperation(Operation, Port, Service, Tail). mk_envelope(M, H) when is_tuple(M) -> mk_envelope([M], H); mk_envelope(M, H) when is_tuple(H) -> mk_envelope(M, [H]); %% mk_envelope(Messages, []) when is_list(Messages) -> #'soap:Envelope'{'Body' = #'soap:Body'{choice = Messages}}; mk_envelope(Messages, Headers) when is_list(Messages),is_list(Headers) -> #'soap:Envelope'{'Body' = #'soap:Body'{choice = Messages}, 'Header' = #'soap:Header'{choice = Headers}}. %%% -------------------------------------------------------------------- %%% Parse a WSDL file and return a 'Model' %%% -------------------------------------------------------------------- initModel(WsdlFile) -> initModel(WsdlFile, ?DefaultPrefix). %% PrefixOrOptions can be a property list that contains the options %% for Erlsom, or a String. If it is a string, this is used as the %% Erlsom 'prefix' option (and the other options are left unspecified). initModel(WsdlFile, PrefixOrOptions) -> Options = case is_string(PrefixOrOptions) of no -> %% It is an option list %% Add the default prefix at the end - it will only be used %% if no other prefix is specified PrefixOrOptions ++ [{prefix, ?DefaultPrefix}]; _ -> %% just the prefix [{prefix, PrefixOrOptions}] end, PrivDir = priv_dir(), initModel2(WsdlFile, Options, PrivDir, undefined, undefined). initModelFile(ConfigFile) -> {ok, ConfigSchema} = erlsom:compile_xsd(config_file_xsd()), %% read (parse) the config file {ok, Config, _} = erlsom:scan_file(ConfigFile, ConfigSchema), #yaws_soap_config{xsd_path = XsdPath, wsdl_file = Wsdl, add_files = AddFiles} = Config, #xsd_file{name = WsdlFile, prefix = Prefix, import_specs = Import} = Wsdl, initModel2(WsdlFile, [{prefix, Prefix}], XsdPath, Import, AddFiles). priv_dir() -> yaws:get_priv_dir(). initModel2(WsdlFile, ErlsomOptions, Path, Import, AddFiles) -> WsdlName = filename:join([Path, "wsdl.xsd"]), IncludeWsdl = {"http://schemas.xmlsoap.org/wsdl/", "wsdl", WsdlName}, {ok, WsdlModel} = erlsom:compile_xsd_file( filename:join([Path, "soap.xsd"]), [{prefix, "soap"}, {include_files, [IncludeWsdl]}]), %% add the xsd model (since xsd is also used in the wsdl) WsdlModel2 = erlsom:add_xsd_model(WsdlModel), Options = ErlsomOptions ++ makeOptions(Import), %% parse Wsdl {Model, Operations} = parseWsdls([WsdlFile], WsdlModel2, Options, {undefined, []}), %% TODO: add files as required %% now compile envelope.xsd, and add Model {ok, EnvelopeModel} = erlsom:compile_xsd_file( filename:join([Path, "envelope.xsd"]), [{prefix, "soap"}]), SoapModel = erlsom:add_model(EnvelopeModel, Model), SoapModel2 = addModels(AddFiles, SoapModel), #wsdl{operations = Operations, model = SoapModel2}. %%% -------------------------------------------------------------------- %%% Parse a list of WSDLs and import (recursively) %%% Returns {Model, Operations} %%% -------------------------------------------------------------------- parseWsdls([], _WsdlModel, _Options, Acc) -> Acc; parseWsdls([WsdlFile | Tail], WsdlModel, Options, {AccModel, AccOperations}) -> {ok, WsdlFileContent} = get_url_file(rmsp(WsdlFile)), {ok, ParsedWsdl, _} = erlsom:scan(WsdlFileContent, WsdlModel), %% get the xsd elements from this model, and hand it over to erlsom_compile. Xsds = getXsdsFromWsdl(ParsedWsdl), %% Now we need to build a list: [{Namespace, Xsd, Prefix}, ...] for %% all the Xsds in the WSDL. %% This list is used when a schema includes one of the other schemas. %% The AXIS java2wsdl tool generates wsdls that depend on this feature. ImportList = makeImportList(Xsds, []), Model2 = addSchemas(Xsds, AccModel, Options, ImportList), Ports = getPorts(ParsedWsdl), Operations = getOperations(ParsedWsdl, Ports), Imports = getImports(ParsedWsdl), Acc2 = {Model2, Operations ++ AccOperations}, %% process imports (recursively, so that imports in the imported files are %% processed as well). %% For the moment, the namespace is ignored on operations etc. %% this makes it a bit easier to deal with imported wsdl's. Acc3 = parseWsdls(Imports, WsdlModel, Options, Acc2), parseWsdls(Tail, WsdlModel, Options, Acc3). %%% -------------------------------------------------------------------- %%% build a list: [{Namespace, Xsd}, ...] for all the Xsds in the WSDL. %%% This list is used when a schema inlcudes one of the other schemas. %%% The AXIS java2wsdl tool generates wsdls that depend on this feature. makeImportList([], Acc) -> Acc; makeImportList([ Xsd | Tail], Acc) -> makeImportList(Tail, [{erlsom_lib:getTargetNamespaceFromXsd(Xsd), undefined, Xsd} | Acc]). %%% -------------------------------------------------------------------- %%% compile each of the schemas, and add it to the model. %%% Returns Model %%% (TODO: using the same prefix for all XSDS makes no sense) %%% -------------------------------------------------------------------- addSchemas([], AccModel, _Options, _ImportList) -> AccModel; addSchemas([Xsd| Tail], AccModel, Options, ImportList) -> Model2 = case Xsd of undefined -> AccModel; _ -> {ok, Model} = erlsom_compile:compile_parsed_xsd( Xsd, [{include_files, ImportList} |Options]), case AccModel of undefined -> Model; _ -> erlsom:add_model(AccModel, Model) end end, addSchemas(Tail, Model2, Options, ImportList). %%% -------------------------------------------------------------------- %%% Get a file from an URL spec. %%% -------------------------------------------------------------------- get_url_file("http://"++_ = URL) -> case httpc:request(URL) of {ok,{{_HTTP,200,_OK}, _Headers, Body}} -> {ok, Body}; {ok,{{_HTTP,RC,Emsg}, _Headers, _Body}} -> error_logger:error_msg("~p: http-request got: ~p~n", [?MODULE, {RC, Emsg}]), {error, "failed to retrieve: "++URL}; {error, Reason} -> error_logger:error_msg("~p: http-request failed: ~p~n", [?MODULE, Reason]), {error, "failed to retrieve: "++URL} end; get_url_file("file://"++Fname) -> {ok, Bin} = file:read_file(Fname), {ok, binary_to_list(Bin)}; %% added this, since this is what is used in many WSDLs (i.e.: just a filename). get_url_file(Fname) -> {ok, Bin} = file:read_file(Fname), {ok, binary_to_list(Bin)}. %%% -------------------------------------------------------------------- %%% Make a HTTP Request %%% -------------------------------------------------------------------- http_request(URL, SoapAction, Request, Options, Headers, ContentType) -> case code:ensure_loaded(ibrowse) of {module, ibrowse} -> %% If ibrowse exist in the path then let's use it... ibrowse_request(URL, SoapAction, Request, Options, Headers, ContentType); _ -> %% ...otherwise, let's use the OTP http client. inets_request(URL, SoapAction, Request, Options, Headers, ContentType) end. inets_request(URL, SoapAction, Request, Options, Headers, ContentType) -> NHeaders = [{"SOAPAction", SoapAction}|Headers], NewHeaders = case proplists:get_value("Host", NHeaders) of undefined -> [{"Host", "localhost:8800"}|NHeaders]; _ -> NHeaders end, NewOptions = [{cookies, enabled}|Options], httpc:set_options(NewOptions), case httpc:request(post, {URL,NewHeaders, ContentType, Request}, [{timeout,?HTTP_REQ_TIMEOUT}], [{sync, true}, {full_result, true}, {body_format, string}]) of {ok,{{_HTTP,200,_OK},ResponseHeaders,ResponseBody}} -> {ok, 200, ResponseHeaders, ResponseBody}; {ok,{{_HTTP,500,_Descr},ResponseHeaders,ResponseBody}} -> {ok, 500, ResponseHeaders, ResponseBody}; {ok,{{_HTTP,ErrorCode,_Descr},ResponseHeaders,ResponseBody}} -> {ok, ErrorCode, ResponseHeaders, ResponseBody}; Other -> Other end. ibrowse_request(URL, SoapAction, Request, Options, Headers, ContentType) -> case start_ibrowse() of ok -> NewHeaders = [{"Content-Type", ContentType}, {"SOAPAction", SoapAction} | Headers], case ibrowse:send_req(URL, NewHeaders, post, Request, Options) of {ok, Status, ResponseHeaders, ResponseBody} -> {ok, list_to_integer(Status), ResponseHeaders, ResponseBody}; {error, Reason} -> {error, Reason} end; error -> {error, "could not start ibrowse"} end. start_ibrowse() -> case ibrowse:start() of {ok, _} -> ok; {error, {already_started, _}} -> ok; _ -> error end. rmsp(Str) -> string:strip(Str, left). make_request_body(Content, []) -> {"text/xml; charset=utf-8", ""++ Content}; make_request_body(Content, AttachedFiles) -> {"application/dime", yaws_dime:encode("" ++ Content, AttachedFiles)}. makeFault(FaultCode, FaultString) -> try "" "" "" "SOAP-ENV:" ++ FaultCode ++ "" ++ "" ++ FaultString ++ "" ++ "" "" "" catch _:_ -> "" "" "" "SOAP-ENV:Server" "Server error" "" "" "" end. %% record http_header is not defined?? findHeader(Label, Headers) -> findHeader0(yaws:to_lower(Label), Headers). findHeader0(_Label, []) -> undefined; findHeader0(Label, [{_,_,Hdr,_,Val}|T]) -> case {Label, yaws:to_lower(Hdr)} of {X,X} -> Val; _ -> findHeader0(Label, T) end; findHeader0(_Label, undefined) -> undefined. makeOptions(undefined) -> []; makeOptions(Import) -> lists:map(fun makeOption/1, Import). %% -record(import_specs, {atts, namespace, prefix, location}). makeOption(#import_specs{namespace = Ns, prefix = Pf, location = Lc}) -> {Ns, Pf, Lc}. addModels(undefined, Model) -> Model; addModels(Import, Model) -> lists:foldl(fun addModel/2, Model, Import). %% -record(xsd_file, {atts, name, prefix, import_specs}). addModel(undefined, Acc) -> Acc; addModel(#xsd_file{name = XsdFile, prefix = Prefix, import_specs = Import}, Acc) -> Options = makeOptions(Import), {ok, Model2} = erlsom:add_xsd_file(XsdFile, [{prefix, Prefix}|Options],Acc), Model2. %% returns [#port{}] %% -record(port, {service, port, binding, address}). getPorts(ParsedWsdl) -> Services = getTopLevelElements(ParsedWsdl, 'wsdl:tService'), getPortsFromServices(Services, []). getPortsFromServices([], Acc) -> Acc; getPortsFromServices([Service|Tail], Acc) -> getPortsFromServices(Tail, getPortsFromService(Service) ++ Acc). getPortsFromService(#'wsdl:tService'{name = Name, port = Ports}) -> getPortsInfo(Ports, Name, []). getPortsInfo([], _Name, Acc) -> Acc; getPortsInfo([#'wsdl:tPort'{name = Name, binding = Binding, choice = [#'soap:tAddress'{location = URL}]} | Tail], ServiceName, Acc) -> getPortsInfo(Tail, ServiceName, [#port{service = ServiceName, port = Name, binding = Binding, address = URL}|Acc]); %% non-soap bindings are ignored. getPortsInfo([#'wsdl:tPort'{} | Tail], ServiceName, Acc) -> getPortsInfo(Tail, ServiceName, Acc). getTopLevelElements(#'wsdl:tDefinitions'{choice = TLElements}, Type) -> getTopLevelElements(TLElements, Type, []). getTopLevelElements([], _Type, Acc) -> Acc; getTopLevelElements([#'wsdl:anyTopLevelOptionalElement'{choice = Tuple}| Tail], Type, Acc) -> case element(1, Tuple) of Type -> getTopLevelElements(Tail, Type, [Tuple|Acc]); _ -> getTopLevelElements(Tail, Type, Acc) end. getImports(Definitions) -> Imports = getTopLevelElements(Definitions, 'wsdl:tImport'), lists:map(fun(Import) -> Import#'wsdl:tImport'.location end, Imports). %% returns [#operation{}] getOperations(ParsedWsdl, Ports) -> Bindings = getTopLevelElements(ParsedWsdl, 'wsdl:tBinding'), getOperationsFromBindings(Bindings, Ports, []). getOperationsFromBindings([], _Ports, Acc) -> Acc; getOperationsFromBindings([Binding|Tail], Ports, Acc) -> getOperationsFromBindings(Tail, Ports, getOperationsFromBinding(Binding, Ports) ++ Acc). getOperationsFromBinding(#'wsdl:tBinding'{name = BindingName, type = BindingType, choice = _Choice, operation = Operations}, Ports) -> %% TODO: get soap info from Choice getOperationsFromOperations(Operations, BindingName, BindingType, Operations, Ports, []). getOperationsFromOperations([], _BindingName, _BindingType, _Operations, _Ports, Acc) -> Acc; getOperationsFromOperations([#'wsdl:tBindingOperation'{name = Name, choice = Choice} | Tail], BindingName, BindingType, Operations, Ports, Acc) -> %% get SOAP action from Choice, case Choice of [#'soap:tOperation'{soapAction = Action}] -> %% lookup Binding in Ports, and create a combined result Ports2 = searchPorts(BindingName, Ports), %% for each port, make an operation record CombinedPorts = combinePorts(Ports2, Name, BindingName, Action), getOperationsFromOperations( Tail, BindingName, BindingType, Operations, Ports, CombinedPorts ++ Acc); _ -> getOperationsFromOperations(Tail, BindingName, BindingType, Operations, Ports, Acc) end. combinePorts(Ports, Name, BindingName, Action) -> combinePorts(Ports, Name, BindingName, Action, []). combinePorts([], _Name, _BindingName, _Action, Acc) -> Acc; combinePorts([#port{service = Service, port = PortName, address = Address} | Tail], Name, BindingName, Action, Acc) -> combinePorts(Tail, Name, BindingName, Action, [#operation{service = Service, port = PortName, operation = Name, binding = BindingName, address = Address, action = Action} | Acc]). searchPorts(BindingName, Ports) -> searchPorts(BindingName, Ports, []). searchPorts(_BindingName, [], Acc) -> Acc; searchPorts(BindingName, [Port | Tail], Acc) -> PortBinding = erlsom_lib:localName(Port#port.binding), case PortBinding of BindingName -> searchPorts(BindingName, Tail, [Port | Acc]); _ -> searchPorts(BindingName, Tail, Acc) end. %% copied from yaws/json.erl is_string([]) -> yes; is_string(List) -> is_string(List, non_unicode). is_string([C|Rest], non_unicode) when C >= 0, C =< 255 -> is_string(Rest, non_unicode); is_string([C|Rest], _) when C =< 65000 -> is_string(Rest, unicode); is_string([], non_unicode) -> yes; is_string([], unicode) -> unicode; is_string(_, _) -> no. getXsdsFromWsdl(Definitions) -> case getTopLevelElements(Definitions, 'wsdl:tTypes') of [#'wsdl:tTypes'{choice = Xsds}] -> Xsds; [] -> [] end. config_file_xsd() -> "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "". yaws-2.0.2/src/yaws_shaper.erl0000664000175000017500000000320512605311412013234 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_shaper.erl %%% Author : Christopher Faulet %%% Purpose : %%% Created : 14 Dec 2010 by Christopher Faulet %%%---------------------------------------------------------------------- -module(yaws_shaper). -author('christopher@yakaz.com'). -export([behaviour_info/1]). %% API -export([ check/2, update/3 ]). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- behaviour_info(callbacks) -> [{check,1}, {update,3}]; behaviour_info(_Other) -> undefined. check(#sconf{shaper=undefined}, _) -> allow; check(#sconf{shaper=Mod}, IP) -> case catch Mod:check(IP) of allow -> allow; {deny, Status, Msg} -> {deny, Status, Msg}; _ -> allow end. update(#sconf{shaper=undefined}, _, _) -> ok; update(#sconf{shaper=Mod}, IP, Req) -> Bytes = case Req#http_request.method of 'HEAD' -> 0; _ -> case yaws:outh_get_contlen() of undefined -> case yaws:outh_get_act_contlen() of undefined -> 0; Actlen -> Actlen end; I2 -> I2 end end, catch Mod:update(IP, 1, Bytes). yaws-2.0.2/src/yaws_xmlrpc.erl0000664000175000017500000001762412605311412013271 00000000000000%% -*- coding: Latin-1 -*- %% Copyright (C) 2003 Joakim Grebenö . %% All rights reserved. %% %% Copyright (C) 2006 Gaspar Chilingarov %% Gurgen Tumanyan %% All rights reserved. %% %% %% Redistribution and use in source and binary forms, with or without %% modification, are permitted provided that the following conditions %% are met: %% %% 1. Redistributions of source code must retain the above copyright %% notice, this list of conditions and the following disclaimer. %% 2. Redistributions in binary form must reproduce the above %% copyright notice, this list of conditions and the following %% disclaimer in the documentation and/or other materials provided %% with the distribution. %% %% THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS %% OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED %% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE %% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY %% DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL %% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE %% GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS %% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, %% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING %% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS %% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -module(yaws_xmlrpc). %%-author('jocke@gleipnir.com'). -author("Gaspar Chilingarov , Gurgen Tumanyan "). -export([handler/2]). -export([handler_session/2, handler_session/3]). %%-define(debug, 1). %%-include("../../yaws/src/yaws_debug.hrl"). -include("../include/yaws_api.hrl"). %%% ###################################################################### %%% public interface %%% %%% %%% use XMLRPC handler which can automagically start sessions if we need %%% handler_session(Args, Handler) -> handler_session(Args, Handler, 'SID'). %%% %%% allow overriding session Cookie name %%% handler_session(Args, Handler, SID_NAME) when is_atom(SID_NAME) -> handler_session(Args, Handler, atom_to_list(SID_NAME)); handler_session(Args, Handler, SID_NAME) -> handler(Args, Handler, {session, SID_NAME}). %%% %%% xmlrpc:handler compatible call %%% no session support will be available handler(Args, Handler) -> handler(Args, Handler, simple). %%% ###################################################################### %%% private functions %%% %%% we should be called from yaws page or module handler(Args, Handler, Type) when is_record(Args, arg) -> case parse_request(Args) of ok -> handle_payload(Args, Handler, Type); {status, StatusCode} -> %% cannot parse request send(Args, StatusCode) end. -define(ERROR_LOG(Reason), error_logger:error_report({?MODULE, ?LINE, Reason})). %%% %%% check that request come in reasonable protocol version and reasonable method %%% parse_request(Args) -> %% {{{ case {(Args#arg.req)#http_request.method, (Args#arg.req)#http_request.version} of {'POST', {1,0}} -> %% ?Debug("HTTP Version 1.0~n", []), ok; {'POST', {1,1}} -> %% ?Debug("HTTP Version 1.1~n", []), ok; {'POST', _HTTPVersion} -> {status, 505}; {_Method, {1,1}} -> {status, 501}; _ -> {status, 400} end. %% }}} handle_payload(Args, Handler, Type) -> Payload = binary_to_list(Args#arg.clidata), %% ?Debug("xmlrpc encoded call ~p ~n", [Payload]), case xmlrpc_decode:payload(Payload) of {ok, DecodedPayload} -> %% ?Debug("xmlrpc decoded call ~p ~n", [DecodedPayload]), eval_payload(Args, Handler, DecodedPayload, Type); {error, Reason} -> ErrMsg = xmlrpc_http:handle_xmlprc_error(Payload, Reason), send(Args, 400, ErrMsg, []) end. %%%%%% %%% call handler/3 and provide session support eval_payload(Args, {M, F}, Payload, {session, CookieName}) -> {SessionValue, Cookie} = case yaws_api:find_cookie_val(CookieName, (Args#arg.headers)#headers.cookie) of [] -> % have no session started, just call handler {undefined, undefined}; Cookie2 -> %% get old session data case yaws_api:cookieval_to_opaque(Cookie2) of {ok, OP} -> yaws_api:cookieval_to_opaque(Cookie2), {OP, Cookie2}; {error, _ErrMsg} -> %% cannot get corresponding session {undefined, undefined} end end, case catch M:F(Args#arg.state, Payload, SessionValue) of {'EXIT', Reason} -> ?ERROR_LOG({M, F, {'EXIT', Reason}}), send(Args, 500); {error, Reason} -> ?ERROR_LOG({M, F, Reason}), send(Args, 500); {false, ResponsePayload} -> %% do not have updates in session data encode_send(Args, 200, ResponsePayload, []); {true, _NewTimeout, NewSessionValue, ResponsePayload} -> %% be compatible with xmlrpc module CO = case NewSessionValue of undefined when Cookie == undefined -> []; %% nothing to do undefined -> %% rpc handler requested session delete yaws_api:delete_cookie_session(Cookie), []; %% XXX: may be return set-cookie with empty val? _ -> %% any other value will stored in session case SessionValue of undefined -> %% got session data and should start %% new session now Cookie1 = yaws_api:new_cookie_session( NewSessionValue), yaws_api:setcookie( CookieName, Cookie1, "/"); %% return set_cookie header _ -> yaws_api:replace_cookie_session( Cookie, NewSessionValue), [] %% nothing to add to yaws data end end, encode_send(Args, 200, ResponsePayload, CO) end; %%% %%% call handler/2 without session support %%% eval_payload(Args, {M, F}, Payload, simple) -> case catch M:F(Args#arg.state, Payload) of {'EXIT', Reason} -> ?ERROR_LOG({M, F, {'EXIT', Reason}}), send(Args, 500); {error, Reason} -> ?ERROR_LOG({M, F, Reason}), send(Args, 500); {false, ResponsePayload} -> encode_send(Args, 200, ResponsePayload, []); {true, _NewTimeout, _NewState, ResponsePayload} -> encode_send(Args, 200, ResponsePayload, []) end. encode_send(Args, StatusCode, Payload, AddOn) -> %% ?Debug("xmlrpc decoded response ~p ~n", [Payload]), case xmlrpc_encode:payload(Payload) of {ok, EncodedPayload} -> %% ?Debug("xmlrpc encoded response ~p ~n", [EncodedPayload]), send(Args, StatusCode, EncodedPayload, AddOn); {error, Reason} -> ?ERROR_LOG({xmlrpc_encode, payload, Payload, Reason}), send(Args, 500) end. send(Args, StatusCode) -> send(Args, StatusCode, "", []). send(Args, StatusCode, Payload, AddOnData) when not is_list(AddOnData) -> send(Args, StatusCode, Payload, [AddOnData]); %%% %%% generate valid yaws response send(_Args, StatusCode, Payload, AddOnData) -> A = [ {status, StatusCode}, {content, "text/xml", Payload}, {header, {content_length, lists:flatlength(Payload) }} ] ++ AddOnData, A. yaws-2.0.2/src/yaws_server.erl0000664000175000017500000055720212605311412013273 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_server.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 16 Jan 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws_server). -author('klacke@hyber.org'). -behaviour(gen_server). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). -include_lib("kernel/include/file.hrl"). -export([mappath/3, vdirpath/3]). %% External exports -export([start_link/1]). -export([safe_decode_path/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([status/0, getconf/0, stats/0, gs_status/0, listen_port/1, ssi/3,ssi/5,ssi/6 ]). %% internal exports -export([gserv/3,acceptor0/2, load_and_run/2, done_or_continue/0, accumulate_content/1, deliver_accumulated/4, deliver_accumulated/1, setup_dirs/1, deliver_dyn_part/8, finish_up_dyn_file/2, gserv_loop/4 ]). %% exports for eunit usage -export([comp_sname/2, wildcomp_salias/2]). -export(['GET'/4, 'POST'/4, 'HEAD'/4, 'TRACE'/4, 'OPTIONS'/4, 'PUT'/4, 'DELETE'/4, 'PATCH'/4]). -import(lists, [member/2, foreach/2, map/2, flatten/1, reverse/1]). -import(yaws_api, [ehtml_expand/1]). -record(gs, {gconf, group, %% list of #sconf{} s ssl, %% ssl | nossl certinfo, %% undefined | #certinfo{} l, %% listen socket mnum = 0, connections = 0, %% number of TCP connections opened now sessions = 0, %% number of active HTTP sessions reqs = 0}). %% total number of processed HTTP requests -record(state, {gc, %% Global conf #gc{} record pairs, %% [{GservPid, ScList}] mnum = 0, %% dyn compiled erl module number embedded %% true if in embedded mode, false otherwise }). %% undefined | mtime from #file_info -record(certinfo, {keyfile, certfile, cacertfile }). -define(elog(X,Y), error_logger:info_msg("*elog ~p:~p: " X, [?MODULE, ?LINE | Y])). start_link(A) -> gen_server:start_link({local, yaws_server}, yaws_server, A, []). status() -> gen_server:call(?MODULE, status, 10000). gs_status() -> [_|Pids] = gen_server:call(?MODULE, pids, 10000), lists:map( fun(P) -> P ! {self(), status}, receive {P, Stat} -> Stat end end, Pids). getconf() -> gen_server:call(?MODULE,getconf, infinity). %% Return the configured port number from the sconf or, if the port number %% is 0 indicating an ephemeral port, retrieve the actual port via sockname listen_port(#sconf{}=SC) -> try lists:foldl(fun(#gs{group=SCs, l=Sock}, Acc) -> case lists:member(SC, SCs) of true -> {ok, {_, Port}} = case SC#sconf.ssl of undefined -> inet:sockname(Sock); _ -> ssl:sockname(Sock) end, %% throw the result to end the fold early throw(Port); false -> Acc end end, [], gs_status()), {error, not_found} catch throw:Port -> Port end. stats() -> {_S, Time} = status(), Diff = calendar:time_difference(Time, calendar:local_time()), L = [begin SC = hd(GS#gs.group), {SC#sconf.listen, SC#sconf.port, GS#gs.connections, GS#gs.sessions, GS#gs.reqs} end || GS <- gs_status()], {Diff, L}. l2a(L) when is_list(L) -> list_to_atom(L); l2a(A) when is_atom(A) -> A. %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %%---------------------------------------------------------------------- init(Env) -> %% #env{Trace, TraceOut, Conf, RunMod, Embedded, Id}) -> process_flag(trap_exit, true), put(start_time, calendar:local_time()), %% for uptime case Env#env.embedded of false -> Config = (catch yaws_config:load(Env)), case Config of {ok, Gconf, Sconfs} -> erase(logdir), ?Debug("GC = ~s~n", [?format_record(Gconf, gconf)]), lists:foreach( fun(Group) -> lists:foreach( fun(_SC) -> ?Debug("SC = ~s~n", [?format_record(_SC, sconf)]) end, Group) end, Sconfs), yaws_trace:setup(Gconf), Res = init2(Gconf, Sconfs, Env#env.runmod, Env#env.embedded, true), yaws_log:setup(Gconf, Sconfs), Res; {error, E} -> case erase(logdir) of undefined -> error_logger:error_msg("Yaws: Bad conf: ~p~n",[E]), init:stop(), {stop, E}; Dir -> GC = yaws_config:make_default_gconf(true, Env#env.id), yaws_log:setup(GC#gconf{logdir = Dir}, []), error_logger:error_msg("Yaws: bad conf: ~s " "terminating~n",[E]), init:stop(), {stop, E} end; EXIT -> error_logger:format("FATAL ~p~n", [EXIT]), erlang:error(badconf) end; true -> {ok, #state{gc = undefined, embedded = Env#env.embedded, pairs = [], mnum = 0}} end. init2(GC, Sconfs, RunMod, Embedded, FirstTime) -> put(gc, GC), yaws_sendfile:check_gc_flags(GC), case GC#gconf.mnesia_dir of MD when length(MD) > 0 -> yaws_debug:format("loading mnesia ~p~n", [MD]), application:set_env(mnesia,dir,MD), mnesia:start(); _ -> ok end, foreach(fun(D) -> yaws_debug:format("Add path ~p~n", [D]), code:add_pathz(D) end, GC#gconf.ebin_dir), yaws_debug:format("Running with id=~p ~n" "~s" "Logging to directory ~p~n", [GC#gconf.id, if ?gc_has_debug(GC) -> "Running with debug checks " "turned on (slower server) \n"; true -> "" end, GC#gconf.logdir]), case Embedded of false -> setup_dirs(GC), case yaws_ctl:start(GC, FirstTime) of ok -> ok; {error, RSN} -> %% Must call init stop here otherwise heart %% will restart us error_logger:format("Failed to start: ~s~n", [RSN]), init:stop(), receive nothing -> ok end end; true -> ok end, runmod(RunMod, GC), yaws_config:compile_and_load_src_dir(GC), L2 = lists:zf(fun(Group) -> start_group(GC, Group) end, yaws_config:load_mime_types_module(GC, Sconfs)), {ok, #state{gc = GC, pairs = L2, mnum = 0, embedded = Embedded}}. start_group(GC, Group) -> FailOnBind = ?gc_fail_on_bind_err(GC), case proc_lib:start_link(?MODULE, gserv, [self(), GC, Group]) of {error, F, A} when FailOnBind == false -> error_logger:error_msg(F, A), false; {error, F, A} -> error_logger:error_msg(F, A), erlang:error(badbind); {error, Reason} when FailOnBind == false -> error_logger:error_msg("FATAL: ~p~n", [Reason]), false; {error, Reason} -> error_logger:error_msg("FATAL: ~p~n", [Reason]), erlang:error(badbind); {Pid, SCs} -> {true, {Pid, SCs}}; none -> false end. %%---------------------------------------------------------------------- %% Func: handle_call/3 %% Returns: {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_call(status, _From, State) -> Reply = {State, get(start_time)}, {reply, Reply, State}; handle_call(id, _From, State) -> {reply, (State#state.gc)#gconf.id, State}; handle_call(pids, _From, State) -> %% for gprof L = map(fun(X) ->element(1, X) end, State#state.pairs), {reply, [self() | L], State}; handle_call(mnum, _From, State) -> Mnum = State#state.mnum +1, {reply, Mnum, State#state{mnum = Mnum}}; %% This is a brutal restart of everything handle_call({setconf, GC, Groups}, _From, State) -> %% First off, terminate all currently running processes Curr = map(fun(X) ->element(1, X) end, State#state.pairs), foreach(fun(Pid) -> gserv_stop(Pid) end, Curr), {ok, State2} = init2(GC, Groups, undef, State#state.embedded, false), {reply, ok, State2}; handle_call(getconf, _From, State) -> Groups = map(fun({_Pid, SCs}) -> SCs end, State#state.pairs), {reply, {ok, State#state.gc, Groups}, State}; %% If cert has changed, server will stop implicitly handle_call(check_certs, _From, State) -> L = lists:map(fun({Pid, _SCs}) -> Pid ! {check_cert_changed, self()}, receive {Pid, YesNo} -> YesNo end end, State#state.pairs), {reply, L, State}; handle_call({update_sconf, Pos, NewSc}, From, State) -> case yaws_config:search_sconf(NewSc, State#state.pairs) of {Pid, OldSc, Group} -> OldPos = string:str(Group, [OldSc]), case (yaws_config:eq_sconfs(OldSc,NewSc) andalso OldPos == Pos) of true -> error_logger:info_msg("Keeping conf for ~s intact\n", [yaws:sconf_to_srvstr(OldSc)]), {reply, ok, State}; false -> Pid ! {update_sconf, Pos, NewSc, OldSc, From, self()}, receive {updated_sconf, Pid, NewSc2} -> P2 = yaws_config:update_sconf(NewSc2, Pos, State#state.pairs), {noreply, State#state{pairs = P2}} after 2000 -> {reply, {error, "Failed to update new conf"}, State} end end; false -> {reply, {error, "No matching group"}, State} end; handle_call({delete_sconf, Sc}, From, State) -> case yaws_config:search_sconf(Sc, State#state.pairs) of {Pid, OldSc, Group} when length(Group) == 1 -> error_logger:info_msg("Terminate whole ~s virt server group \n", [yaws:sconf_to_srvstr(OldSc)]), gserv_stop(Pid), NewPairs = lists:keydelete(Pid, 1, State#state.pairs), {reply, ok, State#state{pairs = NewPairs}}; {Pid, OldSc, _Group} -> Pid ! {delete_sconf, OldSc, From}, P2 = yaws_config:delete_sconf(OldSc, State#state.pairs), {noreply, State#state{pairs = P2}}; false -> {reply, {error, "No matching group"}, State} end; handle_call({add_sconf, Pos, Sc}, From, State) -> case yaws_config:search_group(Sc, State#state.pairs) of [{Pid, _Group}] -> Pid ! {add_sconf, From, Pos, Sc, self()}, receive {added_sconf, Pid, Sc2} -> P2 = yaws_config:update_sconf(Sc2, Pos, State#state.pairs), {noreply, State#state{pairs = P2}} after 2000 -> {reply, {error, "Failed to add new conf"}, State} end; [] -> %% Need to create a new group error_logger:info_msg("Creating new virt server ~s\n", [yaws:sconf_to_srvstr(Sc)]), GC = State#state.gc, case start_group(GC, [Sc]) of false -> {reply, ok, State}; {true, Pair} -> P2 = [Pair | State#state.pairs], {reply, ok, State#state{pairs = P2}} end end; handle_call({update_gconf, GC}, _From, State) -> lists:foreach(fun({Pid, _Group}) -> Pid ! {update_gconf, GC} end, State#state.pairs), %% no need to tell yaws_log, new vals must be compatible put(gc, GC), {reply, ok, State#state{gc = GC}}. %%---------------------------------------------------------------------- %% Func: handle_cast/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%---------------------------------------------------------------------- %% Func: handle_info/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_info({Pid, certchanged}, State) -> {noreply, State#state{pairs = lists:keydelete(Pid, 1, State#state.pairs)}}; handle_info({'EXIT', Pid, Reason}, State) -> case lists:keysearch(Pid, 1, State#state.pairs) of {value, _} -> %% one of our gservs died error_logger:format("yaws: FATAL gserv died ~p~n", [Reason]), erlang:error(restartme); false -> ignore end, {noreply, State}; handle_info(_Msg, State) -> ?Debug("GOT ~p~n", [_Msg]), {noreply, State}. %%---------------------------------------------------------------------- %% Func: terminate/2 %% Purpose: Shutdown the server %% Returns: any (ignored by gen_server) %%---------------------------------------------------------------------- terminate(_Reason, State) -> foreach(fun({Pid, _GP}) -> gserv_stop(Pid) end, State#state.pairs), ok. do_listen(GC, SC) -> case SC#sconf.ssl of undefined -> {nossl, undefined, gen_tcp_listen(SC#sconf.port, listen_opts(SC))}; SSL -> {ssl, certinfo(SSL), ssl_listen(SC#sconf.port, ssl_listen_opts(GC, SC, SSL))} end. certinfo(SSL) -> #certinfo{ keyfile = if SSL#ssl.keyfile /= undefined -> case file:read_file_info(SSL#ssl.keyfile) of {ok, FI} -> FI#file_info.mtime; _ -> undefined end; true -> undefined end, certfile = if SSL#ssl.certfile /= undefined -> case file:read_file_info(SSL#ssl.certfile) of {ok, FI} -> FI#file_info.mtime; _ -> undefined end; true -> undefined end, cacertfile = if SSL#ssl.cacertfile /= undefined -> case file:read_file_info(SSL#ssl.cacertfile) of {ok, FI} -> FI#file_info.mtime; _ -> undefined end; true -> undefined end }. gen_tcp_listen(Port, Opts) -> ?Debug("TCP Listen ~p:~p~n", [Port, Opts]), gen_tcp:listen(Port, Opts). ssl_listen(Port, Opts) -> ?Debug("SSL Listen ~p:~p~n", [Port, Opts]), ssl:listen(Port, Opts). gserv(_Top, _, []) -> proc_lib:init_ack(none); %% One server per IP we listen to gserv(Top, GC, Group0) -> process_flag(trap_exit, true), ?TC([{record, GC, gconf}]), put(gc, GC), put(top, Top), Group1 = map(fun(SC) -> setup_ets(SC) end, Group0), Group = map(fun(SC) -> case ?sc_has_statistics(SC) of true -> start_stats(SC); false -> SC end end, Group1), SC = hd(Group), case do_listen(GC, SC) of {SSLBOOL, CertInfo, {ok, Listen}} -> lists:foreach(fun(XSC) -> call_start_mod(XSC) end, Group), error_logger:info_msg( "Yaws: Listening to ~s:~w for <~p> virtual servers:~s~n", [inet_parse:ntoa(SC#sconf.listen), SC#sconf.port, length(Group), catch map( fun(S) -> io_lib:format("~n - ~s under ~s", [yaws:sconf_to_srvstr(S), S#sconf.docroot]) end, Group) ]), proc_lib:init_ack({self(), Group}), GS = #gs{gconf = GC, group = Group, ssl = SSLBOOL, certinfo = CertInfo, l = Listen}, Last = initial_acceptor(GS), gserv_loop(GS#gs{sessions = 1}, [], 0, Last); {_,_,Err} -> error_logger:format("Yaws: Failed to listen ~s:~w : ~p~n", [inet_parse:ntoa(SC#sconf.listen), SC#sconf.port, Err]), proc_lib:init_ack({error, "Can't listen to socket: ~p ",[Err]}), exit(normal) end. setup_dirs(GC) -> Dir = yaws:id_dir(GC#gconf.id), Ctl = yaws:ctl_file(GC#gconf.id), ok = filelib:ensure_dir(Ctl), case file:list_dir(Dir) of {ok, LL} -> foreach( fun(F) -> file:delete(filename:join([Dir, F])) end, LL -- ["CTL"]); {error, RSN} -> error_logger:format("Failed to list ~p probably " "due to permission errs: ~p", [Dir, RSN]), erlang:error(RSN) end. setup_ets(SC) -> E = ets:new(yaws_code, [public, set]), ets:insert(E, {num_files, 0}), ets:insert(E, {num_bytes, 0}), SC#sconf{ets = E}. clear_ets_complete(SC) -> case SC#sconf.ets of undefined -> setup_ets(SC); E -> ets:match_delete(E,'_'), ets:insert(E, {num_files, 0}), ets:insert(E, {num_bytes, 0}), SC end. start_stats(SC) -> {ok, Pid} = yaws_stats:start_link(), SC#sconf{stats = Pid}. gserv_loop(GS, Ready, Rnum, Last) -> receive {From , status} -> From ! {self(), GS}, ?MODULE:gserv_loop(GS, Ready, Rnum, Last); {_From, next, Accepted} when Ready == [] -> close_accepted_if_max(GS,Accepted), New = acceptor(GS), GS2 = GS#gs{sessions = GS#gs.sessions + 1, connections = GS#gs.connections + 1}, ?MODULE:gserv_loop(GS2, Ready, Rnum, New); {_From, next, Accepted} -> close_accepted_if_max(GS,Accepted), [{_Then, R}|RS] = Ready, R ! {self(), accept}, GS2 = GS#gs{connections=GS#gs.connections + 1}, ?MODULE:gserv_loop(GS2, RS, Rnum-1, R); {_From, decrement} -> GS2 = GS#gs{connections=GS#gs.connections - 1}, ?MODULE:gserv_loop(GS2, Ready, Rnum, Last); {From, done_client, Int} -> GS2 = if Int == 0 -> GS#gs{connections = GS#gs.connections - 1}; Int > 0 -> GS#gs{reqs = GS#gs.reqs+Int, connections = GS#gs.connections - 1} end, PoolSize = (GS#gs.gconf)#gconf.acceptor_pool_size, if Rnum == PoolSize -> From ! {self(), stop}, ?MODULE:gserv_loop(GS2, Ready, Rnum, Last); Rnum < PoolSize -> %% cache this process for 10 secs ?MODULE:gserv_loop(GS2, [{yaws:get_time_tuple(), From} | Ready], Rnum+1, Last) end; {'EXIT', Pid, Reason} -> case get(top) of Pid when Reason /= shutdown -> error_logger:format("Top proc died, terminate gserv",[]), {links, Ls} = process_info(self(), links), foreach(fun(X) -> unlink(X), exit(X, shutdown) end, Ls), exit(noserver); Pid -> {links, Ls} = process_info(self(), links), foreach(fun(X) -> unlink(X), exit(X, shutdown) end, Ls), exit(normal); Top when Reason == failaccept -> error_logger:format( "Accept proc died, terminate gserv",[]), {links, Ls} = process_info(self(), links), %% do not send exit signal to yaws_server process Ls1 = Ls -- [Top], foreach(fun(X) -> unlink(X), exit(X, shutdown) end, Ls1), exit(noserver); _ -> GS2 = GS#gs{sessions = GS#gs.sessions - 1}, if Pid == Last -> %% probably died due to new code loaded; if we %% don't start a new acceptor here we end up with %% no active acceptor error_logger:format("Last acceptor died (~p), " "restart it", [Reason]), New = acceptor(GS), ?MODULE:gserv_loop(GS2, Ready, Rnum, New); true -> case lists:keysearch(Pid, 2, Ready) of {value, _} -> Ready1 = lists:keydelete(Pid, 2, Ready), ?MODULE:gserv_loop(GS2, Ready1, Rnum-1, Last); false -> ?MODULE:gserv_loop(GS2, Ready, Rnum, Last) end end end; {From, stop} -> unlink(From), %% Close the socket and stop acceptors stop_ready(Ready, Last), if GS#gs.ssl == nossl -> gen_tcp:close(GS#gs.l); GS#gs.ssl == ssl -> ssl:close(GS#gs.l) end, %% Stop yaws_stats processes, if needed foreach(fun(#sconf{stats=Pid}) when is_pid(Pid) -> yaws_stats:stop(Pid); (_) -> ok end, GS#gs.group), %% Close softly all opened connections {links, Ls1} = process_info(self(), links), foreach(fun(X) when is_pid(X) -> unlink(X), X ! {self(), suspend}, exit(X, shutdown); (_) -> ok end, Ls1), WaitFun = fun(_, 0, Pids) -> Pids; (_, _, []) -> []; (F, Secs, Pids0) -> timer:sleep(1000), Pids1 = lists:filter(fun(X) when is_pid(X) -> is_process_alive(X); (_) -> false end, Pids0), F(F, Secs-1, Pids1) end, Ls2 = WaitFun(WaitFun, 60, Ls1), %% Kill all remaining connections foreach(fun(X) -> exit(X, kill) end, Ls2), From ! {self(), ok}, exit(normal); %% This code will shutdown all ready procs as well as the %% acceptor() {update_sconf, Pos, NewSc, OldSc, From, Updater} -> case lists:member(OldSc, GS#gs.group) of false -> error_logger:error_msg("gserv: No found SC ~p/~p~n", [OldSc, GS#gs.group]), erlang:error(nosc); true -> Pid = OldSc#sconf.stats, error_logger:info_msg("update_sconf: Stats pid ~p~n",[Pid]), case Pid of undefined -> ok; Pid when is_pid(Pid) -> yaws_stats:stop(Pid) end, NewSc1 = case ?sc_has_statistics(NewSc) of true -> start_stats(NewSc); false -> NewSc end, stop_ready(Ready, Last), NewSc2 = clear_ets_complete(NewSc1), GS2 = GS#gs{group = yaws:insert_at( NewSc2, Pos, lists:delete(OldSc, GS#gs.group) )}, Ready2 = [], Updater ! {updated_sconf, self(), NewSc2}, gen_server:reply(From, ok), error_logger:info_msg("Updating sconf for server ~s~n", [yaws:sconf_to_srvstr(NewSc2)]), New = acceptor(GS2), ?MODULE:gserv_loop(GS2, Ready2, 0, New) end; {delete_sconf, OldSc, From} -> case lists:member(OldSc, GS#gs.group) of false -> error_logger:error_msg("gserv: No found SC ~n",[]), erlang:error(nosc); true -> Pid = OldSc#sconf.stats, stop_ready(Ready, Last), GS2 = GS#gs{group = lists:delete(OldSc,GS#gs.group)}, Ready2 = [], case ?sc_has_statistics(OldSc) of true -> error_logger:info_msg("delete_sconf: Pid= ~p~n", [Pid]), yaws_stats:stop(Pid); false -> ok end, ets:delete(OldSc#sconf.ets), gen_server:reply(From, ok), error_logger:info_msg("Deleting sconf for server ~s~n", [yaws:sconf_to_srvstr(OldSc)]), New = acceptor(GS2), ?MODULE:gserv_loop(GS2, Ready2, 0, New) end; {add_sconf, From, Pos, SC0, Adder} -> SC = case ?sc_has_statistics(SC0) of true -> {ok, Pid} = yaws_stats:start_link(), error_logger:info_msg("add_sconf: Pid= ~p~n", [Pid]), SC0#sconf{stats=Pid}; false -> SC0 end, stop_ready(Ready, Last), SC2 = setup_ets(SC), GS2 = GS#gs{group = yaws:insert_at(SC2, Pos, GS#gs.group)}, Ready2 = [], Adder ! {added_sconf, self(), SC2}, gen_server:reply(From, ok), error_logger:info_msg("Adding sconf for server ~s~n", [yaws:sconf_to_srvstr(SC)]), New = acceptor(GS2), ?MODULE:gserv_loop(GS2, Ready2, 0, New); {check_cert_changed, From} -> Changed = case GS#gs.ssl of ssl -> CertInfo = GS#gs.certinfo, case lists:any( fun(SC) -> certinfo(SC#sconf.ssl) =/= CertInfo end, GS#gs.group) of true -> yes; false -> no end; nossl -> no end, if Changed == no -> From ! {self(), no}, ?MODULE:gserv_loop(GS, Ready, Rnum, Last); Changed == yes -> error_logger:info_msg( "Stopping ~s due to cert change\n", [yaws:sconf_to_srvstr(hd(GS#gs.group))]), {links, Ls0} = process_info(self(), links), Ls = Ls0 -- [get(top)], foreach(fun(X) -> unlink(X), exit(X, shutdown) end, Ls), From ! {self(), yes}, unlink(get(top)), get(top) ! {self(), certchanged}, exit(normal) end; {update_gconf, GC} -> stop_ready(Ready, Last), GS2 = GS#gs{gconf = GC}, Ready2 = [], put(gc, GC), error_logger:info_msg("Updating gconf \n",[]), New = acceptor(GS2), ?MODULE:gserv_loop(GS2, Ready2, 0, New) after (10 * 1000) -> %% collect old procs, to save memory {NowMega, NowSecs, _} = yaws:get_time_tuple(), R2 = lists:filter(fun({{ThenMega, ThenSecs, _}, Pid}) -> if NowMega > ThenMega; (NowSecs > (ThenSecs + 8)) -> Pid ! {self(), stop}, false; true -> true end end, Ready), ?MODULE:gserv_loop(GS, R2, length(R2), Last) end. stop_ready(Ready, Last) -> error_logger:info_msg("stop_ready(~p, ~p)~n", [Ready, Last]), unlink(Last), exit(Last, shutdown), lists:foreach( fun({_,Pid}) -> Pid ! {self(), stop} end, Ready). gserv_stop(Gpid) -> case is_process_alive(Gpid) of true -> Gpid ! {self(), stop}, receive {Gpid, ok} -> ok end; false -> ok end. call_start_mod(SC) -> case SC#sconf.start_mod of undefined -> ok; Mod0 -> Mod = l2a(Mod0), case code:ensure_loaded(Mod) of {module, Mod} -> error_logger:info_msg( "Yaws: calling start_mod: ~p:start/1~n", [Mod]), spawn(Mod, start, [SC]); Err -> error_logger:format("Cannot load module ~p: ~p~n", [Mod,Err]) end end. listen_opts(SC) -> InetType = if is_tuple( SC#sconf.listen), size( SC#sconf.listen) == 8 -> [inet6]; true -> [] end, Opts = [binary, {ip, SC#sconf.listen}, {packet, http}, {packet_size, 16#4000}, {reuseaddr, true}, {active, false} | proplists:get_value(listen_opts, SC#sconf.soptions, []) ] ++ InetType, ?Debug("tcp listen options: ~p", [Opts]), Opts. ssl_listen_opts(GC, SC, SSL) -> InetType = if is_tuple( SC#sconf.listen), size( SC#sconf.listen) == 8 -> [inet6]; true -> [] end, Opts = [binary, {ip, SC#sconf.listen}, {packet, http}, {packet_size, 16#4000}, {reuseaddr, true}, {active, false} | ssl_listen_opts(GC, SSL)] ++ InetType ++ proplists:get_value(listen_opts, SC#sconf.soptions, []), ?Debug("ssl listen options: ~p", [Opts]), Opts. ssl_listen_opts(GC, SSL) -> L = [if SSL#ssl.keyfile /= undefined -> {keyfile, SSL#ssl.keyfile}; true -> false end, if SSL#ssl.certfile /= undefined -> {certfile, SSL#ssl.certfile}; true -> false end, if SSL#ssl.cacertfile /= undefined -> {cacertfile, SSL#ssl.cacertfile}; true -> false end, if SSL#ssl.dhfile /= undefined -> {dhfile, SSL#ssl.dhfile}; true -> false end, if SSL#ssl.verify /= undefined -> {verify, SSL#ssl.verify}; true -> false end, if SSL#ssl.fail_if_no_peer_cert /= undefined -> {fail_if_no_peer_cert, SSL#ssl.fail_if_no_peer_cert}; true -> false end, if SSL#ssl.password /= undefined -> {password, SSL#ssl.password}; true -> false end, if SSL#ssl.ciphers /= undefined -> {ciphers, SSL#ssl.ciphers}; true -> false end, if SSL#ssl.protocol_version /= undefined -> {versions, SSL#ssl.protocol_version}; true -> false end, if SSL#ssl.depth /= undefined -> {depth, SSL#ssl.depth}; true -> false end, if SSL#ssl.secure_renegotiate /= undefined -> {secure_renegotiate, SSL#ssl.secure_renegotiate}; true -> false end, if SSL#ssl.client_renegotiation /= undefined andalso ?SSL_CLIENT_RENEGOTIATION == true -> {client_renegotiation, SSL#ssl.client_renegotiation}; true -> false end, if SSL#ssl.honor_cipher_order /= undefined andalso ?HONOR_CIPHER_ORDER == true -> {honor_cipher_order, SSL#ssl.honor_cipher_order}; true -> false end, ?SSL_LOG_ALERT, if ?gc_use_old_ssl(GC) -> {ssl_imp, old}; true -> {ssl_imp, new} end ], filter_false(L). filter_false(L) -> [X || X <- L, X /= false]. do_accept(GS) when GS#gs.ssl == nossl -> ?Debug("wait in accept ... ~n",[]), gen_tcp:accept(GS#gs.l); do_accept(GS) when GS#gs.ssl == ssl -> ssl:transport_accept(GS#gs.l). initial_acceptor(GS) -> acceptor(GS). acceptor(GS) -> case (GS#gs.gconf)#gconf.process_options of [] -> proc_lib:spawn_link(?MODULE, acceptor0, [GS, self()]); Opts -> %% as we tightly controlled what is set in options, we can %% blindly add "link" to get a linked process as per default %% case and use the provided options. proc_lib:spawn_opt(?MODULE, acceptor0, [GS, self()], [link | Opts]) end. acceptor0(GS, Top) -> ?TC([{record, GS, gs}]), put(gserv_pid, Top), put(gc, GS#gs.gconf), yaws_trace:open(), X = do_accept(GS), Top ! {self(), next, X}, case X of {ok, Client} -> if GS#gs.ssl == ssl -> case ssl:ssl_accept( Client, (GS#gs.gconf)#gconf.keepalive_timeout ) of ok -> ok; {error, closed} -> Top ! {self(), decrement}, exit(normal); {error, esslaccept} -> %% Don't log SSL esslaccept to error log since it %% seems this is what we get on portscans and %% similar ?Debug("SSL accept failed: ~p~n", [esslaccept]), Top ! {self(), decrement}, exit(normal); {error, Reason} -> error_logger:format("SSL accept failed: ~p~n", [Reason]), Top ! {self(), decrement}, exit(normal) end; true -> ok end, {IP,Port} = peername(Client, GS#gs.ssl), put(trace_filter, yaws_trace:get_filter()), Res = (catch aloop(Client, {IP,Port}, GS, 0)), %% Skip closing the socket, as required by web sockets & stream %% processes. CloseSocket = (get(outh) =:= undefined) orelse (done_or_continue() =:= done), case CloseSocket of false -> ok; true -> if GS#gs.ssl == nossl -> gen_tcp:close(Client); GS#gs.ssl == ssl -> ssl:close(Client) end end, case Res of {ok, Int} when is_integer(Int) -> Top ! {self(), done_client, Int}; {'EXIT', normal} -> Top ! {self(), decrement}, exit(normal); {'EXIT', shutdown} -> exit(shutdown); {'EXIT', {error, einval}} -> %% Typically clients that close their end of the socket %% don't log. Happens all the time. Top ! {self(), decrement}, exit(normal); {'EXIT', {{error, einval}, _}} -> Top ! {self(), decrement}, exit(normal); {'EXIT', {{badmatch, {error, einval}}, _}} -> Top ! {self(), decrement}, exit(normal); {'EXIT', {error, closed}} -> Top ! {self(), decrement}, exit(normal); {'EXIT', {{error, closed}, _}} -> Top ! {self(), decrement}, exit(normal); {'EXIT', {{error, econnreset},_}} -> Top ! {self(), decrement}, exit(normal); {'EXIT', Reason2} -> error_logger:error_msg("Yaws process died: ~p~n", [Reason2]), Top ! {self(), decrement}, exit(shutdown) end, %% we cache processes receive {'EXIT', Top, Error} -> exit(Error); {Top, stop} -> exit(normal); {Top, accept} -> erase_transients(), acceptor0(GS, Top) end; {error, Reason} when ((Reason == timeout) or (Reason == einval) or (Reason == normal) or (Reason == econnaborted)) -> %% The econnaborted is %% caused by recieving a RST when a SYN or SYN+ACK was expected. %% einval is reported to happen, it could be accept attempts %% on just recently reconfigured servers through --hup ... ??? Top ! {self(), done_client, 0}, receive {Top, stop} -> exit(normal); {Top, accept} -> acceptor0(GS, Top) end; {error, closed} -> %% This is what happens when we call yaws --stop Top ! {self(), decrement}, exit(normal); {error, Reason} when ((Reason == emfile) or (Reason == enfile)) -> error_logger:format("yaws: Failed to accept - no more " "file descriptors - terminating: ~p~n", [Reason]), exit(failaccept); ERR -> %% When we fail to accept, the correct thing to do %% is to terminate yaws as an application, if we're running %% yaws as a standalone webserver, we want to restart the %% entire webserver, preferably through heart %% typical errors here are shortage of fds or memory error_logger:format("yaws: Failed to accept - terminating: ~p~n", [ERR]), exit(failaccept) end. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- aloop(CliSock, {IP,Port}=IPPort, GS, Num) -> case yaws_trace:get_type(GS#gs.gconf) of undefined -> ok; _ when Num =:= 0 -> yaws_trace:write(from_client, ?F("New (~p) connection from ~s:~w~n", [GS#gs.ssl,inet_parse:ntoa(IP),Port])); _ -> ok end, process_flag(trap_exit, false), init_db(), SSL = GS#gs.ssl, Head = yaws:http_get_headers(CliSock, SSL), process_flag(trap_exit, true), ?Debug("Head = ~p~n", [Head]), case Head of {error, {too_many_headers, ReqTooMany}} -> %% RFC 6585 status code 431 ?Debug("Request headers too large~n", []), case pick_sconf(GS#gs.gconf, #headers{}, GS#gs.group) of undefined -> deliver_400(CliSock, ReqTooMany); SC -> put(sc, SC), put(outh, #outh{}), deliver_431(CliSock, ReqTooMany) end, {ok, Num+1}; {Req0, H0} when Req0#http_request.method /= bad_request -> {Req, H} = fix_abs_uri(Req0, H0), ?Debug("{Req, H} = ~p~n", [{Req, H}]), case pick_sconf(GS#gs.gconf, H, GS#gs.group) of undefined -> deliver_400(CliSock, Req), {ok, Num+1}; SC -> put(outh, #outh{}), put(sc, SC), DispatchResult = case SC#sconf.dispatch_mod of undefined -> continue; DispatchMod -> Arg = make_arg(SC, CliSock, IPPort, H, Req, undefined), ok = yaws:setopts(CliSock, [{packet, raw}, {active, false}], yaws:is_ssl(SC)), DispatchMod:dispatch(Arg) end, case DispatchResult of done -> erase_transients(), case exceed_keepalive_maxuses(GS, Num) of true -> {ok, Num+1}; false -> aloop(CliSock, IPPort, GS, Num+1) end; closed -> %% Dispatcher closed the socket erase_transients(), {ok, Num+1}; continue -> ?Debug("SC: ~s", [?format_record(SC, sconf)]), ?TC([{record, SC, sconf}]), ?Debug("Headers = ~s~n", [?format_record(H, headers)]), ?Debug("Request = ~s~n", [?format_record(Req, http_request)]), run_trace_filter(GS, IP, Req, H), yaws_stats:hit(), check_keepalive_maxuses(GS, Num), Call = case yaws_shaper:check(SC, IP) of allow -> call_method(Req#http_request.method,CliSock, IPPort,Req,H); {deny, Status, Msg} -> deliver_xxx(CliSock, Req, Status, Msg) end, Call2 = fix_keepalive_maxuses(Call), handle_method_result(Call2, CliSock, IPPort, GS, Req, H, Num) end end; closed -> case yaws_trace:get_type(GS#gs.gconf) of undefined -> ok; _ -> yaws_trace:write(from_client, "closed\n") end, {ok, Num}; _ -> % not even HTTP traffic exit(normal) end. run_trace_filter(GS, IP, Req, H) -> case {yaws_trace:get_type(GS#gs.gconf), get(trace_filter)} of {undefined, _} -> ok; {_, undefined} -> RStr = yaws_api:reformat_request(Req), HStr = yaws:headers_to_str(H), yaws_trace:write(from_client, ?F("~s~n~s~n", [RStr, HStr])), ok; {_, FilterFun} -> case FilterFun(inet_parse:ntoa(IP),Req,H) of true -> RStr = yaws_api:reformat_request(Req), HStr = yaws:headers_to_str(H), yaws_trace:write(from_client, ?F("~s~n~s~n", [RStr, HStr])), ok; false -> put(gc, (GS#gs.gconf)#gconf{trace = false}) end end. %% Checks how many times keepalive has been used and updates the %% process dictionary outh variable if required to say that the %% connection has exceeded its maxuses. check_keepalive_maxuses(GS, Num) -> Flag = exceed_keepalive_maxuses(GS, Num), put(outh, (get(outh))#outh{exceedmaxuses=Flag}). exceed_keepalive_maxuses(GS, Num) -> case (GS#gs.gconf)#gconf.keepalive_maxuses of nolimit -> false; 0 -> false; N when Num+1 < N -> false; _N -> true end. %% Change to Res to 'done' if we've exceeded our maxuses. fix_keepalive_maxuses(Res) -> case Res of continue -> case (get(outh))#outh.exceedmaxuses of true -> done; % no keepalive this time! _ -> Res end; _ -> Res end. %% keep original dictionary but filter out eventual previous init_db %% in erase_transients/0 init_db() -> put(init_db, lists:keydelete(init_db, 1, get())). erase_transients() -> %% flush all messages. %% If exit signal is received from the gserv process, rethrow it Top = get(gserv_pid), Fun = fun(G) -> receive {'EXIT', Top, Reason} -> exit(Reason); _X -> G(G) after 0 -> ok end end, Fun(Fun), I = get(init_db), if I == undefined -> ok; is_list(I) -> erase(), %% Need to keep init_db in case we do not enter aloop (i.e. init:db) %% again as R12B-5 requires proc_lib keys in dict while exiting... put(init_db, I), lists:foreach(fun({K,V}) -> put(K,V) end, I) end. handle_method_result(Res, CliSock, {IP,Port}, GS, Req, H, Num) -> case Res of continue -> yaws_shaper:update(get(sc), IP, Req), maybe_access_log(IP, Req, H), erase_transients(), aloop(CliSock, {IP,Port}, GS, Num+1); done -> yaws_shaper:update(get(sc), IP, Req), maybe_access_log(IP, Req, H), erase_transients(), {ok, Num+1}; {page, P} -> %% Because the request is rewritten but the body is the same, we %% keep post_parse and erase query_parse. erase(query_parse), put(outh, #outh{}), case P of {Options, Page} -> %% We got additional headers for the page to deliver. %% %% Might be useful for `Vary' or `Content-Location'. %% %% These headers are stored to be set later to preserve %% it during the next loop. put(page_options, Options); Page -> ok end, %% `is_reentrant_request' flag is used to correctly identify the url %% type put(is_reentrant_request, true), %% Renew #sconf{} to restore docroot/xtra_docroots fields OldSC = get(sc), NewSC = pick_sconf(GS#gs.gconf, H, GS#gs.group), put(sc, NewSC#sconf{appmods = OldSC#sconf.appmods}), %% Rewrite the request NextReq = Req#http_request{path = {abs_path, Page}}, %% Renew #arg{}: keep clidata, state and cont Arg0 = case get(yaws_arg) of undefined -> #arg{}; A -> A end, Arg1 = make_arg(CliSock, {IP,Port}, H, NextReq, Arg0#arg.clidata), Arg2 = Arg1#arg{orig_req = Arg0#arg.orig_req, cont = Arg0#arg.cont, state = Arg0#arg.state}, %% Get the number of bytes already read and do the reentrant call CliDataPos = case get(client_data_pos) of undefined -> 0; Pos -> Pos end, Call = handle_request(CliSock, Arg2, CliDataPos), Call2 = fix_keepalive_maxuses(Call), handle_method_result(Call2, CliSock, {IP,Port}, GS, NextReq, H, Num) end. peername(CliSock, ssl) -> case ssl:peername(CliSock) of {ok, Res} -> Res; _ -> {unknown, unknown} end; peername(CliSock, nossl) -> case inet:peername(CliSock) of {ok, Res} -> Res; _ -> {unknown, unknown} end. deepforeach(_F, []) -> ok; deepforeach(F, [H|T]) -> deepforeach(F, H), deepforeach(F, T); deepforeach(F, X) -> F(X). fix_abs_uri(Req, H) -> case Req#http_request.path of {absoluteURI, _Scheme, Host0, Port, RawPath} -> Host = case Port of P when is_integer(P) -> Host0 ++ [$: | integer_to_list(P)]; % Is this ok? _ -> Host0 end, {Req#http_request{path={abs_path, RawPath}}, H#headers{host=Host}}; _ -> {Req, H} end. %% Case-insensitive compare servername and ignore any optional :Port %% postfix. This is performance-sensitive code, so if you change it, %% measure it. comp_sname([], []) -> true; comp_sname([$:|_], [$:|_]) -> true; comp_sname([$:|_], []) -> true; comp_sname([], [$:|_]) -> true; comp_sname([$:|_], _) -> false; comp_sname(_, [$:|_]) -> false; comp_sname([], _) -> false; comp_sname(_, []) -> false; comp_sname([C1|T1], [C2|T2]) -> case string:to_lower(C1) == string:to_lower(C2) of true -> comp_sname(T1, T2); false -> false end. %% Same thing than comp_sname but here we compare a pattern containing %% wildcards: %% - '*' matches any sequence of zero or more characters %% - '?' matches one character unless that character is a period ('.') wildcomp_salias([], []) -> true; wildcomp_salias([$:|_], [$:|_]) -> true; wildcomp_salias([$:|_], []) -> true; wildcomp_salias([], [$:|_]) -> true; wildcomp_salias([$:|_], _) -> false; wildcomp_salias(_, [$:|_]) -> false; wildcomp_salias([], _) -> false; wildcomp_salias(_, []) -> false; wildcomp_salias([$.|_], [$?|_]) -> false; wildcomp_salias([_|T1], [$?|T2]) -> wildcomp_salias(T1, T2); wildcomp_salias(_, [$*]) -> true; wildcomp_salias([_|T1]=Str, [$*|T2]=Pattern) -> case wildcomp_salias(Str, T2) of true -> true; false -> wildcomp_salias(T1, Pattern) end; wildcomp_salias([C1|T1], [C2|T2]) -> case string:to_lower(C1) == string:to_lower(C2) of true -> wildcomp_salias(T1, T2); false -> false end. pick_sconf(GC, H, Group) -> case H#headers.host of undefined when ?gc_pick_first_virthost_on_nomatch(GC) -> hd(Group); {[Host|_]} when ?gc_pick_first_virthost_on_nomatch(GC) -> pick_host(GC, Host, Group, Group); {_} -> %% HTTP spec does not allow multiple Host headers undefined; Host -> pick_host(GC, Host, Group, Group) end. %% Compare Host against [] in case caller sends an empty Host header pick_host(GC, Host, SCs, Group) when Host == []; Host == undefined; SCs == [] -> if ?gc_pick_first_virthost_on_nomatch(GC) -> hd(Group); true -> yaws_debug:format("Drop req since ~p doesn't match any " "servername \n", [Host]), undefined end; pick_host(GC, Host, [SC|T], Group) -> case comp_sname(Host, SC#sconf.servername) of true -> SC; false -> Res = lists:any(fun(Alias) -> wildcomp_salias(Host, Alias) end, SC#sconf.serveralias), case Res of true -> SC; false -> pick_host(GC, Host, T, Group) end end. maybe_auth_log(Item, ARG) -> SC=get(sc), case ?sc_has_auth_log(SC) of false -> ok; true -> Req = ARG#arg.req, {IP,_} = ARG#arg.client_ip_port, Path = safe_decode_path(Req#http_request.path), yaws_log:authlog(SC, IP, Path, Item) end. maybe_access_log(Ip, Req, H) -> SC=get(sc), case ?sc_has_access_log(SC) of true -> Time = timer:now_diff(yaws:get_time_tuple(), get(request_start_time)), yaws_log:accesslog(SC, Ip, Req, H, get(outh), Time); false -> ignore end. safe_decode_path(Path) -> case (catch decode_path(Path)) of {'EXIT', _} -> "/undecodable_path"; Val -> Val end. decode_path({abs_path, Path}) -> yaws_api:url_decode(Path). %% ret: continue | done 'GET'(CliSock, IPPort, Req, Head) -> no_body_method(CliSock, IPPort, Req, Head). 'POST'(CliSock, IPPort, Req, Head) -> ?Debug("POST Req=~s~n H=~s~n", [?format_record(Req, http_request), ?format_record(Head, headers)]), body_method(CliSock, IPPort, Req, Head). un_partial({partial, Bin}) -> Bin; un_partial(Bin) -> Bin. call_method(Method, CliSock, IPPort, Req, H) -> case Method of F when is_atom(F) -> ?MODULE:F(CliSock, IPPort, Req, H); L when is_list(L) -> handle_extension_method(L, CliSock, IPPort, Req, H) end. 'HEAD'(CliSock, IPPort, Req, Head) -> put(acc_content, discard), no_body_method(CliSock, IPPort, Req, Head). not_implemented(CliSock, _IPPort, Req, Head) -> SC=get(sc), ok = yaws:setopts(CliSock, [{packet, raw}, binary], yaws:is_ssl(SC)), flush(CliSock, Head#headers.content_length, Head#headers.transfer_encoding), deliver_501(CliSock, Req). 'TRACE'(CliSock, IPPort, Req, Head) -> not_implemented(CliSock, IPPort, Req, Head). 'OPTIONS'(CliSock, IPPort, Req, Head) -> case Req#http_request.path of '*' -> % Handle "*" as per RFC2616 section 5.1.2 deliver_options(CliSock, Req, ['GET', 'HEAD', 'OPTIONS', 'PUT', 'POST', 'DELETE']); _ -> no_body_method(CliSock, IPPort, Req, Head) end. 'PUT'(CliSock, IPPort, Req, Head) -> ?Debug("PUT Req=~p~n H=~p~n", [?format_record(Req, http_request), ?format_record(Head, headers)]), SC=get(sc), case ?sc_has_dav(SC) of true -> %% body is handled by yaws_dav:put/1 ok = yaws:setopts(CliSock, [{packet, raw}, binary], yaws:is_ssl(SC)), ARG = make_arg(CliSock, IPPort, Head, Req, undefined), handle_request(CliSock, ARG, 0); false -> body_method(CliSock, IPPort, Req, Head) end. 'DELETE'(CliSock, IPPort, Req, Head) -> body_method(CliSock, IPPort, Req, Head). 'PATCH'(CliSock, IPPort, Req, Head) -> ?Debug("PATCH Req=~p~n H=~p~n", [?format_record(Req, http_request), ?format_record(Head, headers)]), body_method(CliSock, IPPort, Req, Head). body_method(CliSock, IPPort, Req, Head) -> SC=get(sc), ok = yaws:setopts(CliSock, [{packet, raw}, binary], yaws:is_ssl(SC)), PPS = SC#sconf.partial_post_size, case yaws_api:get_header(Head, {lower, "expect"}) of undefined -> ok; Value -> case yaws:to_lower(Value) of "100-continue" -> deliver_100(CliSock); _ -> ok end end, Res = case Head#headers.content_length of undefined -> case yaws:to_lower(Head#headers.transfer_encoding) of "chunked" -> get_chunked_client_data(CliSock, yaws:is_ssl(SC)); _ -> <<>> end; Len when is_integer(PPS) -> Int_len = list_to_integer(Len), if Int_len < 0 -> {error, content_length_overflow}; Int_len == 0 -> <<>>; PPS < Int_len -> {partial, get_client_data(CliSock, PPS, yaws:is_ssl(SC))}; true -> get_client_data(CliSock, Int_len, yaws:is_ssl(SC)) end; Len when PPS == nolimit -> Int_len = list_to_integer(Len), if Int_len < 0 -> {error, content_length_overflow}; Int_len == 0 -> <<>>; true -> get_client_data(CliSock, Int_len, yaws:is_ssl(SC)) end end, case Res of {error, Reason} -> error_logger:format("Invalid Request: ~p~n", [Reason]), deliver_400(CliSock, Req); Bin -> ?Debug("Request data = ~s~n", [binary_to_list(un_partial(Bin))]), ARG = make_arg(CliSock, IPPort, Head, Req, Bin), handle_request(CliSock, ARG, size(un_partial(Bin))) end. no_body_method(CliSock, IPPort, Req, Head) -> SC=get(sc), ok = yaws:setopts(CliSock, [{packet, raw}, binary], yaws:is_ssl(SC)), flush(CliSock, Head#headers.content_length, Head#headers.transfer_encoding), Head1 = Head#headers{content_length=undefined, transfer_encoding=undefined}, ARG = make_arg(CliSock, IPPort, Head1, Req, undefined), handle_request(CliSock, ARG, 0). make_arg(CliSock0, IPPort, Head, Req, Bin) -> SC = get(sc), make_arg(SC, CliSock0, IPPort, Head, Req, Bin). make_arg(SC, CliSock0, IPPort, Head, Req, Bin) -> CliSock = case yaws:is_ssl(SC) of nossl -> CliSock0; ssl -> {ssl, CliSock0} end, ARG = #arg{clisock = CliSock, client_ip_port = IPPort, headers = Head, req = Req, orig_req = Req, opaque = SC#sconf.opaque, pid = self(), docroot = SC#sconf.docroot, docroot_mount = "/", clidata = Bin }, apply(SC#sconf.arg_rewrite_mod, arg_rewrite, [ARG]). %% PATCH is not an extension method, but at this time the Erlang HTTP %% request line parser doesn't know about it so it comes back to us as a %% string rather than an atom, which causes call_method to call %% handle_extension_method. If and when the parser is updated to accept %% PATCH, we'll get it back as an atom and this following clause will be %% unnecessary. handle_extension_method("PATCH", CliSock, IPPort, Req, Head) -> 'PATCH'(CliSock, IPPort, Req#http_request{method = 'PATCH'}, Head); handle_extension_method(_Method, CliSock, IPPort, Req, Head) -> body_method(CliSock, IPPort, Req, Head). %% Return values: %% continue, done, {page, Page} handle_request(CliSock, ARG, _N) when is_record(ARG#arg.state, rewrite_response) -> State = ARG#arg.state, ?Debug("SrvReq=~s - RwResp=~s~n",[?format_record(ARG#arg.req, http_request), ?format_record(State, rewrite_response)]), OutH = #outh{status = State#rewrite_response.status, chunked = false, date = yaws:make_date_header(), server = yaws:make_server_header()}, put(outh, OutH), deepforeach(fun(X) -> case X of {header, H} -> yaws:accumulate_header(H); _ -> ok end end, State#rewrite_response.headers), case State#rewrite_response.content of <<>> -> deliver_accumulated(CliSock); _ -> %% Define a default content type if needed case yaws:outh_get_content_type() of undefined -> Mime = mime_types:default_type(get(sc)), yaws:outh_set_content_type(Mime); _ -> ok end, accumulate_content(State#rewrite_response.content), deliver_accumulated(ARG, CliSock, undefined, final) end, done_or_continue(); handle_request(CliSock, ARG, N) -> Req = ARG#arg.req, ?Debug("SrvReq=~s~n",[?format_record(Req, http_request)]), case Req#http_request.path of {abs_path, RawPath} -> case (catch yaws_api:url_decode_q_split(RawPath)) of {'EXIT', _} -> %% weird broken cracker requests deliver_400(CliSock, Req); {DecPath, QueryPart} -> %% http://? %% DecPath is stored in arg.server_path and is equiv to %%SCRIPT_PATH + PATH_INFO (where PATH_INFO may be empty) QueryString = case QueryPart of [] -> undefined; _ -> QueryPart end, %% by this stage, ARG#arg.docroot_mount is either "/" , %% or has been set by a rewrite module. %%!todo - retrieve 'vdir' definitions from main part of %% config file rather than %% rely on rewrite module to dig them out of opaque. ARGvdir = ARG#arg.docroot_mount, %% here we make sure that the conf file, or any rewrite mod %% wrote nothing, or something sensible into %% arg.docroot_mount %% It must be empty, or of the form "/path/" where path %% may be further slash-separated. %% %%!todo - review - is handle_request %% (which is presumably performance %%sensitive) really the place for sanity checks? %% Presumably this sort of check is trivial enough %% that it'll have negligible impact. VdirSanity = case ARGvdir of "/" -> sane; [$/|_] -> case string:right(ARGvdir,1) of "/" when length(ARGvdir) > 2 -> sane; _ -> loopy end; _ -> loopy end, case VdirSanity of loopy -> %%!todo - log somewhere? error_logger:format( "BAD arg.docroot_mount data: '~p'\n",[ARGvdir]), deliver_xxx(CliSock, Req, 500), exit(normal); _ -> ok end, SC = get(sc), IsRev = is_revproxy(ARG, DecPath, SC), IsRedirect = is_redirect_map(DecPath, SC#sconf.redirect_map), case {IsRev, IsRedirect} of {_, {true, Redir}} -> ARG1 = ARG#arg{server_path = DecPath, querydata = QueryString}, deliver_redirect_map(CliSock, Req, ARG1, Redir, N); {false, _} -> %%'main' branch so to speak. Most requests %% pass through here. UT = url_type(DecPath, ARG#arg.docroot, ARG#arg.docroot_mount), ARG1 = ARG#arg{server_path = DecPath, querydata = QueryString, fullpath = UT#urltype.fullpath, prepath = UT#urltype.dir, pathinfo = UT#urltype.pathinfo}, handle_normal_request(CliSock, ARG1, UT, SC#sconf.authdirs, N); {{true, PP}, _} -> UT = #urltype{type = appmod, data = {yaws_revproxy, []}}, ARG1 = ARG#arg{server_path = DecPath, querydata = QueryString, state = PP}, handle_normal_request(CliSock, ARG1, UT, SC#sconf.authdirs, N) end end; {scheme, _Scheme, _RequestString} -> deliver_501(CliSock, Req); _ -> % for completeness deliver_400(CliSock, Req) end. handle_normal_request(CliSock, ARG, UT = #urltype{type=error}, _, N) -> handle_ut(CliSock, ARG, UT, N); handle_normal_request(CliSock, ARG, UT, Authdirs, N) -> {IsAuth, ARG1} = case is_auth(ARG, Authdirs) of {true, User} -> {true, set_auth_user(ARG, User)}; E -> {E, ARG} end, case IsAuth of true -> %%!todo - remove special treatment of appmod here. (after suitable %% deprecation period) - prepath & pathinfo are applicable to other %% types of dynamic url too replace: appmoddata with pathinfo & %% appmod_prepath with prepath. case UT#urltype.type of appmod -> {_Mod, PathInfo} = UT#urltype.data, Appmoddata = case PathInfo of undefined -> undefined; "/" -> "/"; _ -> lists:dropwhile(fun(C) -> C == $/ end, PathInfo) end, ARG2 = ARG1#arg{appmoddata = Appmoddata, appmod_prepath = UT#urltype.dir}; _ -> ARG2 = ARG1 end, handle_ut(CliSock, ARG2, UT, N); false_403 -> deliver_403(CliSock, ARG1#arg.orig_req); {false, AuthMethods, Realm} -> UT1 = #urltype{type = {unauthorized, AuthMethods, Realm}, path = ARG1#arg.server_path}, handle_ut(CliSock, ARG1, UT1, N) end. set_auth_user(ARG, User) -> H = ARG#arg.headers, Auth = case H#headers.authorization of {undefined, _, _} -> {User, undefined, undefined}; {_User, Pass, Orig} -> {User, Pass, Orig}; undefined -> {User, undefined, undefined}; E -> E end, H2 = H#headers{authorization = Auth}, ARG#arg{headers = H2}. filter_auths(Auths, Req_dir) -> case filter_auths(Auths, Req_dir, []) of [] when Req_dir =:= "/" -> []; [] -> filter_auths(Auths, filename:dirname(Req_dir)); As -> As end. filter_auths([], _, Auths) -> lists:reverse(Auths); filter_auths([A=#auth{dir=Req_dir}|T], Req_dir, Auths) -> filter_auths(T, Req_dir, [A|Auths]); filter_auths([_|T], Req_dir, Auths) -> filter_auths(T, Req_dir, Auths). %% Call is_auth(...)/5 with a default value. is_auth(#arg{req=Req, orig_req=Req}=ARG, L) -> case lists:keyfind(ARG#arg.docroot, 1, L) of {_, Auths} -> is_req_auth(ARG, Auths, true); false -> true end; is_auth(ARG, L) -> case lists:keyfind(ARG#arg.docroot, 1, L) of {_, Auths} -> is_req_auth(ARG, Auths, is_orig_req_auth(ARG,Auths,true)); false -> true end. is_orig_req_auth(#arg{orig_req=OrigReq, headers=H}=ARG, Auths, Ret) -> case OrigReq#http_request.path of {abs_path, RawPath} -> case (catch yaws_api:url_decode_q_split(RawPath)) of {'EXIT', _} -> Ret; {DecPath, _} -> is_auth(ARG, DecPath, H, filter_auths(Auths, DecPath), {true, []}) end; _ -> Ret end. is_req_auth(#arg{server_path=Req_dir, headers=H}=ARG, Auths, Ret) -> case is_auth(ARG, Req_dir, H, filter_auths(Auths, Req_dir), {true, []}) of true -> Ret; Else -> Else end. %% Either no authentication was done or all methods returned false is_auth(_ARG, _Req_dir, _H, [], {Ret, Auth_headers}) -> yaws:outh_set_auth(Auth_headers), Ret; is_auth(ARG, Req_dir, H, [Auth_methods|T], {_Ret, Auth_headers}) -> Auth_H = H#headers.authorization, case handle_auth(ARG, Auth_H, Auth_methods, false) of %% If we auth using an authmod we need to return User %% so that we can set it in ARG. {false, A} -> L = A#auth.headers, Auth_methods1 = Auth_methods#auth{realm = A#auth.realm, outmod = A#auth.outmod}, is_auth(ARG, Req_dir, H, T, {{false, Auth_methods1, A#auth.realm}, L ++ Auth_headers}); Is_auth -> %% true, {true, User} or false_403 Is_auth end. handle_auth(#arg{client_ip_port={IP,_}}=ARG, Auth_H, #auth{acl={AllowIPs, DenyIPs, Order}}=Auth_methods, Ret) -> Fun = fun(IpMask) -> yaws:match_ipmask(IP, IpMask) end, Ret1 = case Auth_methods of #auth{users=[],pam=false,mod=[]} -> true; _ -> Ret end, case {AllowIPs, DenyIPs, Order} of {_, all, deny_allow} -> case lists:any(Fun, AllowIPs) of true -> handle_auth(ARG, Auth_H, Auth_methods#auth{acl=none}, Ret1); false -> false_403 end; {all, _, deny_allow} -> handle_auth(ARG, Auth_H, Auth_methods#auth{acl=none}, Ret1); {_, _, deny_allow} -> case lists:any(Fun, DenyIPs) of true -> case lists:any(Fun, AllowIPs) of true -> handle_auth(ARG, Auth_H, Auth_methods#auth{acl=none}, Ret1); false -> false_403 end; false -> handle_auth(ARG, Auth_H, Auth_methods#auth{acl=none}, Ret1) end; {_, all, allow_deny} -> false_403; {all, _, allow_deny} -> case lists:any(Fun, DenyIPs) of true -> false_403; false -> handle_auth(ARG, Auth_H, Auth_methods#auth{acl=none}, Ret1) end; {_, _, allow_deny} -> case lists:any(Fun, AllowIPs) of true -> case lists:any(Fun, DenyIPs) of true -> false_403; false -> handle_auth(ARG, Auth_H, Auth_methods#auth{acl=none}, Ret1) end; false -> false_403 end end; handle_auth(_ARG, _Auth_H, #auth{users=[],pam=false,mod=[]}, true) -> true; handle_auth(ARG, _Auth_H, Auth_methods=#auth{users=[],pam=false,mod=[]}, Ret) -> maybe_auth_log({401, Auth_methods#auth.realm}, ARG), {Ret, Auth_methods}; handle_auth(ARG, Auth_H, Auth_methods = #auth{mod = Mod}, Ret) when Mod /= [] -> case catch Mod:auth(ARG, Auth_methods) of {'EXIT', Reason} -> L = ?F("authmod crashed ~n~p:auth(~p, ~n ~p) \n" "Reason: ~p~n" "Stack: ~p~n", [Mod, ARG, Auth_methods, Reason, erlang:get_stacktrace()]), handle_crash(ARG, L), CliSock = case yaws_api:get_sslsocket(ARG#arg.clisock) of {ok, SslSock} -> SslSock; undefined -> ARG#arg.clisock end, deliver_accumulated(CliSock), exit(normal); %% appmod means the auth headers are undefined, i.e. false. %% TODO: change so that authmods simply return true/false {true, User} -> {true, User}; true -> true; false -> handle_auth(ARG, Auth_H, Auth_methods#auth{mod = []}, Ret); {false, Realm} -> handle_auth(ARG, Auth_H, Auth_methods#auth{mod=[], realm=Realm}, Ret); {appmod, Module} -> handle_auth(ARG, Auth_H, Auth_methods#auth{mod=[], outmod=Module}, Ret); _ -> maybe_auth_log(403, ARG), false_403 end; %% if the headers are undefined we do not need to check Pam or Users handle_auth(ARG, undefined, Auth_methods, Ret) -> handle_auth(ARG, undefined, Auth_methods#auth{pam = false, users= []}, Ret); handle_auth(ARG, {User, Password, OrigString}, Auth_methods = #auth{pam = Pam}, Ret) when Pam /= false -> case yaws_pam:auth(User, Password) of {yes, _} -> maybe_auth_log({ok, User}, ARG), true; {no, _Rsn} -> handle_auth(ARG, {User, Password, OrigString}, Auth_methods#auth{pam = false}, Ret) end; handle_auth(ARG, {User, Password, OrigString}, Auth_methods = #auth{users = Users}, Ret) when Users /= [] -> case member({User, Password}, Users) of true -> maybe_auth_log({ok, User}, ARG), true; false -> handle_auth(ARG, {User, Password, OrigString}, Auth_methods#auth{users = []}, Ret) end. is_revproxy(ARG, Path, SC = #sconf{revproxy = RevConf}) -> IsFwd = ?sc_forward_proxy(SC), %% Note: these are mututally exclusive. case {IsFwd, RevConf} of {false, []} -> false; {false, _} -> is_revproxy1(Path, RevConf); {true, _} -> {true, #proxy_cfg{prefix="/", url=fwdproxy_url(ARG)}} end. is_revproxy1(_,[]) -> false; is_revproxy1(Path, RevConf) -> case lists:keyfind(Path, #proxy_cfg.prefix, RevConf) of #proxy_cfg{}=R -> {true, R}; false when Path == "/" -> false; false -> is_revproxy1(filename:dirname(Path), RevConf) end. is_redirect_map(_, []) -> false; is_redirect_map(Path, RedirMap) -> case lists:keyfind(Path, 1, RedirMap) of {Path, _Code, _Url, _AppendMod}=E -> {true, E}; false when Path == "/" -> false; false -> is_redirect_map(filename:dirname(Path), RedirMap) end. %% Find out what which module to call when urltype is unauthorized %% Precedence is: %% 1. SC#errormod401 if it's not default %% 2. outmod if defined %% 3. yaws_outmod get_unauthorized_outmod(_Req_dir, _Auth, Errormod401) when Errormod401 /= yaws_outmod -> Errormod401; get_unauthorized_outmod(_Req_dir, Auth, Errormod401) -> case Auth#auth.outmod /= [] of true -> Auth#auth.outmod; false -> Errormod401 end. %% Return values: %% continue, done, {page, Page} handle_ut(CliSock, ARG, UT = #urltype{type = regular}, _N) -> Req = ARG#arg.req, H = ARG#arg.headers, Regular_allowed = ['GET', 'HEAD', 'OPTIONS'], IsReentrantRequest = erase(is_reentrant_request), if %% Do not check http method for reentrant requests IsReentrantRequest == true; Req#http_request.method == 'GET'; Req#http_request.method == 'HEAD' -> ETag = yaws:make_etag(UT#urltype.finfo), Range = case H#headers.if_range of [34|_] = Range_etag when Range_etag /= ETag -> all; _ -> requested_range( H#headers.range, (UT#urltype.finfo)#file_info.size) end, case Range of error -> deliver_416( CliSock, Req, (UT#urltype.finfo)#file_info.size); _ -> Do_deliver = case Req#http_request.method of 'HEAD' -> fun() -> deliver_accumulated(CliSock), done end; _ -> fun() -> deliver_file(CliSock, Req, UT, Range) end end, case H#headers.if_none_match of undefined -> case H#headers.if_match of undefined -> case H#headers.if_modified_since of undefined -> yaws:outh_set_static_headers (Req, UT, H, Range), maybe_set_page_options(), Do_deliver(); UTC_string -> case yaws:is_modified_p( UT#urltype.finfo, UTC_string) of true -> yaws:outh_set_static_headers (Req, UT, H, Range), maybe_set_page_options(), Do_deliver(); false -> yaws:outh_set_304_headers( Req, UT, H), maybe_set_page_options(), deliver_accumulated( CliSock), done_or_continue() end end; Line -> case member(ETag, yaws:split_sep(Line, $,)) of true -> yaws:outh_set_static_headers( Req, UT, H, Range), maybe_set_page_options(), Do_deliver(); false -> deliver_xxx(CliSock, Req, 412) end end; Line -> case member(ETag,yaws:split_sep(Line, $,)) of true -> yaws:outh_set_304_headers(Req, UT, H), maybe_set_page_options(), deliver_accumulated(CliSock), done_or_continue(); false -> yaws:outh_set_static_headers (Req, UT, H, Range), Do_deliver() end end end; Req#http_request.method == 'OPTIONS' -> deliver_options(CliSock, Req, Regular_allowed); true -> deliver_405(CliSock, Req, Regular_allowed) end; handle_ut(CliSock, ARG, UT = #urltype{type = yaws}, N) -> Req = ARG#arg.req, H = ARG#arg.headers, ?Debug("UT = ~s~n", [?format_record(UT, urltype)]), Yaws_allowed = ['GET', 'POST', 'HEAD', 'OPTIONS'], if Req#http_request.method == 'GET'; Req#http_request.method == 'POST'; Req#http_request.method == 'HEAD' -> yaws:outh_set_dyn_headers(Req, H, UT), maybe_set_page_options(), do_yaws(CliSock, ARG, UT, N); Req#http_request.method == 'OPTIONS' -> deliver_options(CliSock, Req, Yaws_allowed); true -> deliver_405(CliSock, Req, Yaws_allowed) end; handle_ut(CliSock, ARG, UT = #urltype{type = {unauthorized, Auth, Realm}}, N) -> Req = ARG#arg.req, H = ARG#arg.headers, SC = get(sc), yaws:outh_set_dyn_headers(Req, H, UT), %% outh_set_dyn headers sets status to 200 by default %% so we need to set it 401 yaws:outh_set_status_code(401), Outmod = get_unauthorized_outmod(UT#urltype.path, Auth, SC#sconf.errormod_401), OutFun = fun (A) -> case catch Outmod:out401(A, Auth, Realm) of {'EXIT', {undef, _}} -> %% Possibly a deprecated warning Outmod:out(A); {'EXIT', Reason} -> exit(Reason); Result -> Result end end, DeliverFun = fun (A) -> finish_up_dyn_file(A, CliSock) end, deliver_dyn_part(CliSock, 0, "appmod", N, ARG, UT, OutFun, DeliverFun); handle_ut(CliSock, ARG, UT = #urltype{type = error}, N) -> Req = ARG#arg.req, H = ARG#arg.headers, SC=get(sc),GC=get(gc), case UT#urltype.type of error when SC#sconf.xtra_docroots == [] -> yaws:outh_set_dyn_headers(Req, H, UT), deliver_dyn_part(CliSock, 0, "404", N, ARG,UT, fun(A)->(SC#sconf.errormod_404): out404(A,GC,SC) end, fun(A)->finish_up_dyn_file(A, CliSock) end ); error -> SC2 = SC#sconf{docroot = hd(SC#sconf.xtra_docroots), xtra_docroots = tl(SC#sconf.xtra_docroots)}, put(sc, SC2), %%!todo - review & change. rewriting the docroot and xtra_docroots %% is not a good way to handle the xtra_docroot feature because %% it makes less information available to the subsequent calls - %% this is especially an issue for a nested ssi. ARG2 = ARG#arg{docroot = SC2#sconf.docroot}, handle_request(CliSock, ARG2, N) end; handle_ut(CliSock, ARG, UT = #urltype{type = directory}, N) -> Req = ARG#arg.req, H = ARG#arg.headers, SC=get(sc), if (?sc_has_dir_listings(SC)) -> Directory_allowed = ['GET', 'HEAD', 'OPTIONS'], IsReentrantRequest = erase(is_reentrant_request), if %% Do not check http method for reentrant requests IsReentrantRequest == true; Req#http_request.method == 'GET'; Req#http_request.method == 'HEAD' -> yaws:outh_set_dyn_headers(Req, H, UT), maybe_set_page_options(), P = UT#urltype.fullpath, yaws_ls:list_directory(ARG, CliSock, UT#urltype.data, P, Req, ?sc_has_dir_all_zip(SC)); Req#http_request.method == 'OPTIONS' -> deliver_options(CliSock, Req, Directory_allowed); true -> deliver_405(CliSock, Req, Directory_allowed) end; true -> handle_ut(CliSock, ARG, #urltype{type = error}, N) end; handle_ut(CliSock, ARG, UT = #urltype{type = redir}, N) -> Req = ARG#arg.req, H = ARG#arg.headers, yaws:outh_set_dyn_headers(Req, H, UT), case yaws:outh_get_doclose() of true -> ok; _ -> flush(CliSock, N, H#headers.content_length, yaws:to_lower(H#headers.transfer_encoding)) end, deliver_302(CliSock, Req, ARG, UT#urltype.path); handle_ut(CliSock, ARG, UT = #urltype{type = appmod}, N) -> Req = ARG#arg.req, H = ARG#arg.headers, yaws:outh_set_dyn_headers(Req, H, UT), maybe_set_page_options(), {Mod,_} = UT#urltype.data, deliver_dyn_part(CliSock, 0, "appmod", N, ARG,UT, fun(A)->Mod:out(A) end, fun(A)->finish_up_dyn_file(A, CliSock) end ); handle_ut(CliSock, ARG, UT = #urltype{type = cgi}, N) -> Req = ARG#arg.req, H = ARG#arg.headers, yaws:outh_set_dyn_headers(Req, H, UT), maybe_set_page_options(), deliver_dyn_part(CliSock, 0, "cgi", N, ARG,UT, fun(A)->yaws_cgi:call_cgi( A,flatten(UT#urltype.fullpath)) end, fun(A)->finish_up_dyn_file(A, CliSock) end ); handle_ut(CliSock, ARG, UT = #urltype{type = fcgi}, N) -> error_logger:error_msg("*** handle_ut: type=fcgi~n"), %%@@@ Req = ARG#arg.req, H = ARG#arg.headers, yaws:outh_set_dyn_headers(Req, H, UT), maybe_set_page_options(), deliver_dyn_part(CliSock, 0, "fcgi", N, ARG,UT, fun(A)->yaws_cgi:call_fcgi_responder(A) end, fun(A)->finish_up_dyn_file(A, CliSock) end ); handle_ut(CliSock, ARG, UT = #urltype{type = dav}, N) -> Req = ARG#arg.req, H = ARG#arg.headers, Next = case Req#http_request.method of 'OPTIONS' -> options; _ when Req#http_request.method == 'GET'; Req#http_request.method == 'HEAD' -> case prim_file:read_file_info(UT#urltype.fullpath) of {ok, FI} when FI#file_info.type == regular -> {regular, FI}; _ -> error end; _Dav when Req#http_request.method == 'PUT'; Req#http_request.method == 'DELETE'; Req#http_request.method == "PROPFIND"; Req#http_request.method == "PROPPATCH"; Req#http_request.method == "LOCK"; Req#http_request.method == "UNLOCK"; Req#http_request.method == "MOVE"; Req#http_request.method == "COPY"; Req#http_request.method == "MKCOL" -> dav; _ -> error end, case Next of error -> handle_ut(CliSock, ARG, #urltype{type = error}, N); options -> deliver_options(CliSock, Req, []); {regular, Finfo} -> handle_ut(CliSock, ARG, UT#urltype{type = regular, finfo = Finfo}, N); dav -> yaws:outh_set_dyn_headers(Req, H, UT), maybe_set_page_options(), deliver_dyn_part(CliSock, 0, "dav", N, ARG,UT, Next, fun(A) -> finish_up_dyn_file(A, CliSock) end ) end; handle_ut(CliSock, ARG, UT = #urltype{type = php}, N) -> Req = ARG#arg.req, H = ARG#arg.headers, SC=get(sc), yaws:outh_set_dyn_headers(Req, H, UT), maybe_set_page_options(), Fun = case SC#sconf.php_handler of {cgi, Exe} -> fun(A)-> yaws_cgi:call_cgi( A,Exe,flatten(UT#urltype.fullpath) ) end; {fcgi, {PhpFcgiHost, PhpFcgiPort}} -> fun(A)-> yaws_cgi:call_fcgi_responder( A, [{app_server_host, PhpFcgiHost}, {app_server_port, PhpFcgiPort}] ) end; {extern, {PhpMod, PhpFun}} -> fun(A) -> PhpMod:PhpFun(A) end; {extern, {PhpNode,PhpMod,PhpFun}} -> fun(A) -> %% Mod:Fun must return rpc:call(PhpNode, PhpMod, PhpFun, [A], infinity) end end, deliver_dyn_part(CliSock, 0, "php", N, ARG,UT, Fun, fun(A)->finish_up_dyn_file(A, CliSock) end ). done_or_continue() -> case yaws:outh_get_doclose() of true -> done; false -> continue; keep_alive -> continue; undefined -> continue end. %% we may have content, new_redir_h(OH, Loc) -> new_redir_h(OH, Loc, 302). new_redir_h(OH, Loc, Status) -> OH2 = OH#outh{status = Status, location = Loc}, put(outh, OH2). %% we must deliver a 302 if the browser asks for a dir %% without a trailing / in the HTTP req %% otherwise the relative urls in /dir/index.html will be broken. %% Note: Here Path is always decoded, so we must encode it deliver_302(CliSock, _Req, Arg, Path) -> ?Debug("in redir 302 ",[]), H = get(outh), SC=get(sc), Scheme = yaws:redirect_scheme(SC), Headers = Arg#arg.headers, EncPath = yaws_api:url_encode(Path), RedirHost = yaws:redirect_host(SC, Headers#headers.host), %% QueryString must be added Loc = case Arg#arg.querydata of undefined -> ["Location: ", Scheme, RedirHost, EncPath, "\r\n"]; [] -> ["Location: ", Scheme, RedirHost, EncPath, "\r\n"]; Q -> ["Location: ", Scheme, RedirHost, EncPath, "?", Q, "\r\n"] end, new_redir_h(H, Loc), deliver_accumulated(CliSock), done_or_continue(). deliver_redirect_map(CliSock, Req, _Arg, {_Prefix, Code, undefined, _Mode}, _N) -> %% Here Code is 1xx, 2xx, 4xx or 5xx ?Debug("in redir ~p", [Code]), deliver_xxx(CliSock, Req, Code); deliver_redirect_map(_CliSock, _Req, Arg, {_Prefix, Code, Path, Mode}, N) when is_list(Path) -> %% Here Code is 1xx, 2xx, 4xx or 5xx ?Debug("in redir ~p", [Code]), Path1 = if Mode == append -> EncPath = yaws_api:url_encode(Arg#arg.server_path), filename:join([Path ++ EncPath]); true -> %% noappend Path end, Page = case Arg#arg.querydata of undefined -> Path1; [] -> Path1; Q -> Path1 ++ "?" ++ Q end, %% Set variables used in handle_method_result/7 put(yaws_arg, Arg), put(client_data_pos, N), {page, {[{status, Code}], Page}}; deliver_redirect_map(CliSock, Req, Arg, {_Prefix, Code, URL, Mode}, N) when is_record(URL, url) -> %% Here Code is 3xx ?Debug("in redir ~p", [Code]), H = get(outh), QueryData = case Arg#arg.querydata of undefined -> []; Q -> Q end, LocPath = if Mode == append -> EncPath = yaws_api:url_encode(Arg#arg.server_path), Path1 = filename:join([URL#url.path ++ EncPath]), yaws_api:format_partial_url( URL#url{path=Path1,querypart=QueryData}, get(sc) ); true -> %% noappend yaws_api:format_partial_url(URL#url{querypart=QueryData}, get(sc)) end, Loc = ["Location: ", LocPath, "\r\n"], {DoClose, _Chunked} = yaws:dcc(Req, Arg#arg.headers), case DoClose of true -> ok; _ -> flush(CliSock, N, (Arg#arg.headers)#headers.content_length, (Arg#arg.headers)#headers.transfer_encoding) end, new_redir_h(H#outh{ connection = yaws:make_connection_close_header(DoClose), doclose = DoClose, server = yaws:make_server_header(), chunked = false, date = yaws:make_date_header() }, Loc, Code), deliver_accumulated(CliSock), done_or_continue(). deliver_options(CliSock, _Req, Options) -> H = #outh{status = 200, doclose = false, chunked = false, server = yaws:make_server_header(), date = yaws:make_date_header(), allow = yaws:make_allow_header(Options)}, put(outh, H), deliver_accumulated(CliSock), continue. deliver_100(CliSock) -> H = #outh{status = 100, doclose = false, chunked = false, server = yaws:make_server_header(), allow = yaws:make_allow_header()}, put(outh, H), deliver_accumulated(CliSock), continue. deliver_xxx(CliSock, _Req, Code) -> deliver_xxx(CliSock, _Req, Code, ""). deliver_xxx(CliSock, _Req, Code, ExtraHtml) -> B = ["

", integer_to_list(Code), $\ , yaws_api:code_to_phrase(Code), "

", ExtraHtml], Sz = iolist_size(B), Server = case get(sc) of undefined -> undefined; _ -> yaws:make_server_header() end, H = #outh{status = Code, doclose = true, chunked = false, server = Server, connection = yaws:make_connection_close_header(true), content_length = yaws:make_content_length_header(Sz), contlen = Sz, content_type = yaws:make_content_type_header("text/html")}, put(outh, H), accumulate_content(B), deliver_accumulated(CliSock), done. deliver_400(CliSock, Req) -> deliver_xxx(CliSock, Req, 400).% Bad Request deliver_403(CliSock, Req) -> deliver_xxx(CliSock, Req, 403). % Forbidden deliver_405(CliSock, Req, Methods) -> Methods_msg = lists:flatten( ["

This resource allows ", yaws:join_sep([atom_to_list(M) || M <- Methods], ", "), "

"]), deliver_xxx(CliSock, Req, 405, Methods_msg). deliver_416(CliSock, _Req, Tot) -> B = ["

416 ", yaws_api:code_to_phrase(416), "

"], Sz = iolist_size(B), H = #outh{status = 416, doclose = true, chunked = false, server = yaws:make_server_header(), connection = yaws:make_connection_close_header(true), content_range = ["Content-Range: */", integer_to_list(Tot), $\r, $\n], content_length = yaws:make_content_length_header(Sz), contlen = Sz, content_type = yaws:make_content_type_header("text/html")}, put(outh, H), accumulate_content(B), deliver_accumulated(CliSock), done. deliver_431(CliSock, Req) -> deliver_xxx(CliSock, Req, 431). deliver_501(CliSock, Req) -> deliver_xxx(CliSock, Req, 501). % Not implemented do_yaws(CliSock, ARG, UT, N) -> Key = UT#urltype.getpath, %% always flat Mtime = mtime(UT#urltype.finfo), SC=get(sc), case ets:lookup(SC#sconf.ets, Key) of [{_Key, spec, Mtime1, Spec, Es}] when Mtime1 == Mtime, Es == 0 -> deliver_dyn_file(CliSock, Spec, ARG, UT, N); Other -> del_old_files(get(gc),Other), {ok, [{errors, Errs}| Spec]} = yaws_compile:compile_file(UT#urltype.fullpath), ?Debug("Spec for file ~s is:~n~p~n",[UT#urltype.fullpath, Spec]), ets:insert(SC#sconf.ets, {Key, spec, Mtime, Spec, Errs}), deliver_dyn_file(CliSock, Spec, ARG, UT, N) end. del_old_files(_, []) -> ok; del_old_files(_GC, [{_FileAtom, spec, _Mtime1, Spec, _}]) -> foreach( fun({mod, _, _, _, Mod, _Func}) -> F=filename:join([yaws:tmpdir(), "yaws", yaws:to_list(Mod) ++ ".erl"]), code:purge(Mod), code:purge(Mod), file:delete(F); (_) -> ok end, Spec). get_client_data(CliSock, Len, SSlBool) -> get_client_data(CliSock, Len, [], SSlBool). get_client_data(_CliSock, 0, Bs, _SSlBool) -> list_to_binary(Bs); get_client_data(CliSock, Len, Bs, SSlBool) -> case yaws:cli_recv(CliSock, Len, SSlBool) of {ok, B} -> get_client_data(CliSock, Len-size(B), [Bs,B], SSlBool); _Other -> error_logger:format("get_client_data: ~p~n", [_Other]), exit(normal) end. %% not nice to support this for ssl sockets get_chunked_client_data(CliSock,SSL) -> SC = get(sc), Val = erase(current_chunk_size), Len = if Val =:= 0 -> %% Last chunk was already read. undefined; Val =:= undefined -> yaws:setopts(CliSock, [binary, {packet, line}],SSL), %% Ignore chunk extentions {N, _Exts} = yaws:get_chunk_header(CliSock, SSL), yaws:setopts(CliSock, [binary, {packet, raw}],SSL), N; true -> Val end, if Len =:= undefined -> %% Do nothing put(current_chunk_size, 0), <<>>; Len == 0 -> put(current_chunk_size, 0), %% Ignore chunk trailer yaws:get_chunk_trailer(CliSock, SSL), <<>>; Len =< SC#sconf.partial_post_size -> B = yaws:get_chunk(CliSock, Len, 0, SSL), yaws:eat_crnl(CliSock,SSL), {partial, list_to_binary(B)}; true -> B = yaws:get_chunk(CliSock, SC#sconf.partial_post_size, 0, SSL), put(current_chunk_size, Len - SC#sconf.partial_post_size), {partial, list_to_binary(B)} end. %% Return values: %% continue, done, {page, Page} deliver_dyn_part(CliSock, % essential params LineNo, YawsFile, % for diagnostic output CliDataPos0, % for `get_more' and `flush' Arg,UT, YawsFun, % call YawsFun(Arg) DeliverCont % call DeliverCont(Arg) % to continue normally ) -> %% Note: yaws_arg and client_data_pos are also used in %% handle_method_result/7 when `{page, Page}' is returned put(yaws_ut, UT), put(yaws_arg, Arg), put(client_data_pos, CliDataPos0), OutReply = try Res = YawsFun(Arg), handle_out_reply(Res, LineNo, YawsFile, UT, Arg) catch Class:Exc -> handle_out_reply({throw, Class, Exc}, LineNo, YawsFile, UT, Arg) end, case OutReply of {get_more, Cont, State} when element(1, Arg#arg.clidata) == partial -> CliDataPos1 = get(client_data_pos), More = get_more_post_data(CliSock, CliDataPos1, Arg), A2 = Arg#arg{clidata=More, cont=Cont, state=State}, deliver_dyn_part( CliSock, LineNo, YawsFile, CliDataPos1+size(un_partial(More)), A2, UT, YawsFun, DeliverCont ); break -> finish_up_dyn_file(Arg, CliSock); {page, Page} -> {page, Page}; Arg2 = #arg{} -> DeliverCont(Arg2); {streamcontent, _, _} -> Priv = deliver_accumulated(Arg, CliSock, undefined, stream), stream_loop_send(Priv, CliSock, 30000); %% For other timeout values (other than 30 second) {streamcontent_with_timeout, _, _, TimeOut} -> Priv = deliver_accumulated(Arg, CliSock, undefined, stream), stream_loop_send(Priv, CliSock, TimeOut); {streamcontent_with_size, Sz, _, _} -> Priv = deliver_accumulated(Arg, CliSock, Sz, stream), stream_loop_send(Priv, CliSock, 30000); {streamcontent_from_pid, _, Pid} -> case yaws:outh_get_content_encoding() of decide -> yaws:outh_set_content_encoding(identity); _ -> ok end, Priv = deliver_accumulated(Arg, CliSock, undefined, stream), wait_for_streamcontent_pid(Priv, CliSock, Pid); {websocket, CallbackMod, Opts} -> %% The handshake passes control over the socket to OwnerPid %% and terminates the Yaws worker! yaws_websockets:start(Arg, CallbackMod, Opts); _ -> DeliverCont(Arg) end. finish_up_dyn_file(Arg, CliSock) -> deliver_accumulated(Arg, CliSock, undefined, final), done_or_continue(). %% do the header and continue deliver_dyn_file(CliSock, Specs, ARG, UT, N) -> Bin = ut_read(UT), deliver_dyn_file(CliSock, Bin, Specs, ARG, UT, N). deliver_dyn_file(CliSock, Bin, [H|T], Arg, UT, N) -> ?Debug("deliver_dyn_file: ~p~n", [H]), case H of {mod, LineNo, YawsFile, NumChars, Mod, out} -> {_, Bin2} = skip_data(Bin, NumChars), deliver_dyn_part(CliSock, LineNo, YawsFile, N, Arg, UT, fun(A)->Mod:out(A) end, fun(A)->deliver_dyn_file(CliSock,Bin2,T,A,UT,0) end); {data, 0} -> deliver_dyn_file(CliSock, Bin, T, Arg, UT, N); {data, NumChars} -> {Send, Bin2} = skip_data(Bin, NumChars), accumulate_content(Send), deliver_dyn_file(CliSock, Bin2, T, Arg, UT, N); {skip, 0} -> deliver_dyn_file(CliSock, Bin, T, Arg, UT, N); {skip, NumChars} -> {_, Bin2} = skip_data(Bin, NumChars), deliver_dyn_file(CliSock, Bin2, T, Arg, UT, N); {binding, NumChars} -> {Send, Bin2} = skip_data(Bin, NumChars), "%%"++Key = binary_to_list(Send), Chunk = case get({binding, Key--"%%"}) of undefined -> Send; Value -> Value end, accumulate_content(Chunk), deliver_dyn_file(CliSock, Bin2, T, Arg, UT, N); {error, NumChars, Str} -> {_, Bin2} = skip_data(Bin, NumChars), accumulate_content(Str), deliver_dyn_file(CliSock, Bin2, T, Arg, UT, N); {verbatim, NumChars, Data} -> {_Send, Bin2} = skip_data(Bin, NumChars), accumulate_content(Data), deliver_dyn_file(CliSock, Bin2, T, Arg, UT, N); yssi -> ok end; deliver_dyn_file(CliSock, _Bin, [], ARG,_UT,_N) -> ?Debug("deliver_dyn: done~n", []), finish_up_dyn_file(ARG, CliSock). -define(unflushed_timeout, 300). stream_loop_send(Priv, CliSock, IdleTimeout) -> stream_loop_send(Priv, CliSock, unflushed, ?unflushed_timeout, IdleTimeout). stream_loop_send(Priv, CliSock, FlushStatus, CurTimeout, IdleTimeout) -> receive {streamcontent, Cont} -> P = send_streamcontent_chunk(Priv, CliSock, Cont), stream_loop_send(P, CliSock, unflushed, ?unflushed_timeout, IdleTimeout); {streamcontent_with_ack, From, Cont} -> % acknowledge after send P = send_streamcontent_chunk(Priv, CliSock, Cont), From ! {self(), streamcontent_ack}, stream_loop_send(P, CliSock, unflushed, ?unflushed_timeout, IdleTimeout); endofstreamcontent -> end_streaming(Priv, CliSock) after CurTimeout -> case FlushStatus of flushed -> erlang:error(stream_timeout); unflushed -> P = sync_streamcontent(Priv, CliSock), stream_loop_send(P, CliSock, flushed, IdleTimeout, IdleTimeout) end end. make_chunk(Data) -> case yaws:outh_get_chunked() of true -> case iolist_size(Data) of 0 -> empty; S -> CRNL = crnl(), {S, [yaws:integer_to_hex(S), CRNL, Data, CRNL]} end; false -> {iolist_size(Data), Data} end. make_final_chunk(Data) -> case yaws:outh_get_chunked() of true -> CRNL = crnl(), case iolist_size(Data) of 0 -> {0, ["0",CRNL,CRNL]}; S -> {S, [yaws:integer_to_hex(S), CRNL, Data, CRNL, "0", CRNL, CRNL]} end; false -> {iolist_size(Data), Data} end. send_streamcontent_chunk(discard, _, _) -> discard; send_streamcontent_chunk(undefined, CliSock, Data) -> case make_chunk(Data) of empty -> ok; {Size, Chunk} -> ?Debug("send ~p bytes to ~p ~n", [Size, CliSock]), yaws:outh_inc_act_contlen(Size), yaws:gen_tcp_send(CliSock, Chunk) end, undefined; send_streamcontent_chunk({Z, Priv}, CliSock, Data) -> ?Debug("send ~p bytes to ~p ~n", [iolist_size(Data), CliSock]), {ok, P, D} = yaws_zlib:gzipDeflate(Z, Priv, iolist_to_binary(Data), none), case make_chunk(D) of empty -> ok; {Size, Chunk} -> yaws:outh_inc_act_contlen(Size), yaws:gen_tcp_send(CliSock, Chunk) end, {Z, P}. sync_streamcontent(discard, _CliSock) -> discard; sync_streamcontent(undefined, _CliSock) -> undefined; sync_streamcontent({Z, Priv}, CliSock) -> ?Debug("syncing~n", []), {ok, P, D} = yaws_zlib:gzipDeflate(Z, Priv, <<>>, sync), case make_chunk(D) of empty -> ok; {Size, Chunk} -> yaws:outh_inc_act_contlen(Size), yaws:gen_tcp_send(CliSock, Chunk) end, {Z, P}. end_streaming(discard, _) -> done_or_continue(); end_streaming(undefined, CliSock) -> ?Debug("end_streaming~n", []), {_, Chunk} = make_final_chunk(<<>>), yaws:gen_tcp_send(CliSock, Chunk), done_or_continue(); end_streaming({Z, Priv}, CliSock) -> ?Debug("end_streaming~n", []), {ok, _P, Data} = yaws_zlib:gzipDeflate(Z, Priv, <<>>, finish), {Size, Chunk} = make_final_chunk(Data), yaws:outh_inc_act_contlen(Size), yaws:gen_tcp_send(CliSock, Chunk), yaws_zlib:gzipEnd(Z), zlib:close(Z), done_or_continue(). %% what about trailers ?? %% vinoski -- I think trailers should be added as an optional argument to %% yaws_api:stream_chunk_end(). The end_streaming() function above could %% then easily deal with sending them. wait_for_streamcontent_pid(Priv, CliSock, ContentPid) -> Ref = erlang:monitor(process, ContentPid), case Priv of discard -> ContentPid ! {discard, self()}; _ -> SC = get(sc), case SC#sconf.ssl of undefined -> gen_tcp:controlling_process(CliSock, ContentPid); _ -> ssl:controlling_process(CliSock, ContentPid) end, ContentPid ! {ok, self()} end, receive endofstreamcontent -> demonitor_streamcontent_pid(Ref); {endofstreamcontent, closed} -> H = get(outh), put(outh, H#outh{doclose = true}), demonitor_streamcontent_pid(Ref); {'DOWN', Ref, _, _, _} -> ok end, done_or_continue(). demonitor_streamcontent_pid(Ref) -> erlang:demonitor(Ref), %% should just use demonitor [flush] option instead? receive {'DOWN', Ref, _, _, _} -> ok after 0 -> ok end. skip_data(Bin, Sz) -> ?Debug("Skip data ~p bytes from", [Sz]), <> = Bin, {Head, Tail}. accumulate_content(Data) -> case get(acc_content) of undefined -> put(acc_content, [Data]); discard -> discard; List -> put(acc_content, [List, Data]) end. %% handle_out_reply(R, ...) %% %% R is a reply or a deep list of replies. The special return values %% `streamcontent', `get_more_data' etc, which are not handled here %% completely but returned, have to be the last element of the list. handle_out_reply(L, LineNo, YawsFile, UT, ARG) when is_list (L) -> handle_out_reply_l(L, LineNo, YawsFile, UT, ARG, undefined); %% yssi, yaws include handle_out_reply({yssi, Yfile}, LineNo, YawsFile, UT, ARG) -> SC = get(sc), %% special case for abs paths UT2=case Yfile of [$/|_] -> url_type( Yfile, ARG#arg.docroot, ARG#arg.docroot_mount); _Else -> %%why lists:flatten? is urltype.dir ever nested more than %% 1 level deep? %%!todo - replace with conc_path if 1 level - or specify that %% urltype fields should be written flat! %% All this deep listing of relatively *short* strings %seems unwieldy. just how much performance can it gain if we %% end up using slower funcs like lists:flatten anyway? %% review!. url_type(lists:flatten(UT#urltype.dir) ++ [$/|Yfile], ARG#arg.docroot, ARG#arg.docroot_mount) end, case UT2#urltype.type of yaws -> Mtime = mtime(UT2#urltype.finfo), Key = UT2#urltype.getpath, CliSock = case yaws_api:get_sslsocket(ARG#arg.clisock) of {ok, SslSock} -> SslSock; undefined -> ARG#arg.clisock end, N = 0, case ets:lookup(SC#sconf.ets, Key) of [{_Key, spec, Mtime1, Spec, Es}] when Mtime1 == Mtime, Es == 0 -> deliver_dyn_file(CliSock, Spec ++ [yssi], ARG, UT2, N); Other -> del_old_files(get(gc), Other), {ok, [{errors, Errs}| Spec]} = yaws_compile:compile_file(UT2#urltype.fullpath), ?Debug("Spec for file ~s is:~n~p~n", [UT2#urltype.fullpath, Spec]), ets:insert(SC#sconf.ets, {Key, spec, Mtime, Spec, Errs}), deliver_dyn_file(CliSock, Spec ++ [yssi], ARG, UT2, N) end; error when SC#sconf.xtra_docroots /= [] -> SC2 = SC#sconf{docroot = hd(SC#sconf.xtra_docroots), xtra_docroots = tl(SC#sconf.xtra_docroots)}, put(sc, SC2), ARG2 = ARG#arg{docroot = SC2#sconf.docroot}, Ret = handle_out_reply({yssi, Yfile}, LineNo, YawsFile, UT, ARG2), put(sc, SC), Ret; _ -> error_logger:format("Failed to yssi ~p~n", [Yfile]), ok end; handle_out_reply({html, Html}, _LineNo, _YawsFile, _UT, _ARG) -> accumulate_content(Html), ok; handle_out_reply({ehtml, E}, _LineNo, _YawsFile, _UT, ARG) -> case safe_ehtml_expand(E) of {ok, Val} -> accumulate_content(Val), ok; {error, ErrStr} -> handle_crash(ARG, ErrStr) end; handle_out_reply({exhtml, E}, _LineNo, _YawsFile, _UT, _A) -> N = count_trailing_spaces(), accumulate_content(yaws_exhtml:format(E, N)), ok; handle_out_reply({exhtml, Value2StringF, E}, _LineNo, _YawsFile, _UT, _A) -> N = count_trailing_spaces(), accumulate_content(yaws_exhtml:format(E, N, Value2StringF)), ok; handle_out_reply({sexhtml, E}, _LineNo, _YawsFile, _UT, _A) -> accumulate_content(yaws_exhtml:sformat(E)), ok; handle_out_reply({sexhtml, Value2StringF, E}, _LineNo, _YawsFile, _UT, _A) -> accumulate_content(yaws_exhtml:sformat(E, Value2StringF)), ok; handle_out_reply({content, MimeType, Cont}, _LineNo,_YawsFile, _UT, _ARG) -> yaws:outh_set_content_type(MimeType), accumulate_content(Cont), ok; handle_out_reply({streamcontent, MimeType, First}, _LineNo,_YawsFile, _UT, _ARG) -> yaws:outh_set_content_type(MimeType), accumulate_content(First), {streamcontent, MimeType, First}; handle_out_reply({streamcontent_with_timeout, MimeType, First, Timeout}, _LineNo,_YawsFile, _UT, _ARG) -> yaws:outh_set_content_type(MimeType), accumulate_content(First), {streamcontent_with_timeout, MimeType, First, Timeout}; handle_out_reply(Res = {page, _Page}, _LineNo,_YawsFile, _UT, _ARG) -> Res; handle_out_reply({streamcontent_with_size, Sz, MimeType, First}, _LineNo,_YawsFile, _UT, _ARG) -> yaws:outh_set_content_type(MimeType), accumulate_content(First), {streamcontent_with_size, Sz, MimeType, First}; handle_out_reply({streamcontent_from_pid, MimeType, Pid}, _LineNo,_YawsFile, _UT, _ARG) -> yaws:outh_set_content_type(MimeType), {streamcontent_from_pid, MimeType, Pid}; handle_out_reply({websocket, _CallbackMod, _Opts}=Reply, _LineNo,_YawsFile, _UT, _ARG) -> yaws:accumulate_header({connection, erase}), Reply; handle_out_reply({header, H}, _LineNo, _YawsFile, _UT, _ARG) -> yaws:accumulate_header(H), ok; handle_out_reply({allheaders, Hs}, _LineNo, _YawsFile, _UT, _ARG) -> yaws:outh_clear_headers(), foreach(fun({header, Head}) -> yaws:accumulate_header(Head) end, Hs), ok; handle_out_reply({status, Code},_LineNo,_YawsFile,_UT,_ARG) when is_integer(Code) -> yaws:outh_set_status_code(Code), ok; handle_out_reply({'EXIT', normal}, _LineNo, _YawsFile, _UT, _ARG) -> exit(normal); handle_out_reply({ssi, File, Delimiter, Bindings}, LineNo, YawsFile, UT, ARG) -> case ssi(File, Delimiter, Bindings, UT, ARG) of {error, Rsn} -> L = ?F("yaws code at~s:~p had the following err:~n~p", [YawsFile, LineNo, Rsn]), handle_crash(ARG, L); OutData -> accumulate_content(OutData), ok end; handle_out_reply(break, _LineNo, _YawsFile, _UT, _ARG) -> break; handle_out_reply({redirect_local, Path}, LN, YF, UT, ARG) -> handle_out_reply({redirect_local, Path, 302}, LN, YF, UT, ARG); %% What about: %% %% handle_out_reply({redirect_local, Path, Status}, LineNo, %% YawsFile, SC, ARG) when string(Path) -> %% handle_out_reply({redirect_local, {any_path, Path}, Status}, LineNo, %% YawsFile, SC, ARG); %% %% It would introduce a slight incompatibility with earlier versions, %% but might be desirable. handle_out_reply({redirect_local, {any_path, URL}, Status}, LineNo, YawsFile, _UT, ARG) -> PathType = case yaws_api:is_absolute_URI(URL) of true -> net_path; false -> case URL of [$/|_] -> abs_path; _ -> rel_path end end, handle_out_reply({redirect_local, {PathType, URL}, Status}, LineNo, YawsFile, _UT, ARG); handle_out_reply({redirect_local, {net_path, URL}, Status}, _LineNo, _YawsFile, _UT, _ARG) -> Loc = ["Location: ", URL, "\r\n"], new_redir_h(get(outh), Loc, Status), ok; handle_out_reply({redirect_local, Path0, Status}, _LineNo,_YawsFile,_UT, ARG) -> SC=get(sc), Path = case Path0 of {abs_path, P} -> P; {rel_path, P} -> {abs_path, RP} = (ARG#arg.req)#http_request.path, case string:rchr(RP, $/) of 0 -> [$/|P]; N -> [lists:sublist(RP, N),P] end; P -> P end, Scheme = yaws:redirect_scheme(SC), Headers = ARG#arg.headers, HostPort = yaws:redirect_host(SC, Headers#headers.host), Loc = ["Location: ", Scheme, HostPort, Path, "\r\n"], new_redir_h(get(outh), Loc, Status), ok; handle_out_reply({redirect, URL}, LN, YF, UT, ARG) -> handle_out_reply({redirect, URL, 302}, LN, YF, UT, ARG); handle_out_reply({redirect, URL, Status}, _LineNo, _YawsFile, _UT, _ARG) -> Loc = ["Location: ", URL, "\r\n"], new_redir_h(get(outh), Loc, Status), ok; handle_out_reply({bindings, L}, _LineNo, _YawsFile, _UT, _ARG) -> foreach(fun({Key, Value}) -> put({binding, Key}, Value) end, L), ok; handle_out_reply(ok, _LineNo, _YawsFile, _UT, _ARG) -> ok; handle_out_reply({'EXIT', Err}, LineNo, YawsFile, _UT, ARG) -> L = ?F("~n~nERROR erlang code crashed:~n " "File: ~s:~w~n" "Reason: ~p~nReq: ~p~n" "Stack: ~p~n", [YawsFile, LineNo, Err, ARG#arg.req, erlang:get_stacktrace()]), handle_crash(ARG, L); handle_out_reply({throw, Class, Exc}, LineNo, YawsFile, _UT, ARG) -> L = ?F("~n~nERROR erlang code threw an uncaught exception:~n " "File: ~s:~w~n" "Class: ~p~nException: ~p~nReq: ~p~n" "Stack: ~p~n", [YawsFile, LineNo, Class, Exc, ARG#arg.req, erlang:get_stacktrace()]), handle_crash(ARG, L); handle_out_reply({get_more, Cont, State}, _LineNo, _YawsFile, _UT, _ARG) -> {get_more, Cont, State}; handle_out_reply(Arg = #arg{}, _LineNo, _YawsFile, _UT, _ARG) -> Arg; handle_out_reply(flush, _LineNo, _YawsFile, _UT, ARG) -> CliSock = case yaws_api:get_sslsocket(ARG#arg.clisock) of {ok, SslSock} -> SslSock; undefined -> ARG#arg.clisock end, Hdrs = ARG#arg.headers, CliDataPos0 = get(client_data_pos), CliDataPos1 = flush(CliSock, CliDataPos0, Hdrs#headers.content_length, yaws:to_lower(Hdrs#headers.transfer_encoding)), put(client_data_pos, CliDataPos1), ok; handle_out_reply(Reply, LineNo, YawsFile, _UT, ARG) -> L = ?F("yaws code at ~s:~p crashed or " "ret bad val:~p ~nReq: ~p", [YawsFile, LineNo, Reply, ARG#arg.req]), handle_crash(ARG, L). handle_out_reply_l([Reply|T], LineNo, YawsFile, UT, ARG, Res) -> case handle_out_reply(Reply, LineNo, YawsFile, UT, ARG) of break -> break; {page, Page} -> {page, Page}; {get_more, Cont, State} -> {get_more, Cont, State}; {streamcontent,_,_}=Reply -> Reply; {streamcontent_with_timeout,_,_,_}=Reply -> Reply; {streamcontent_with_size,_,_,_}=Reply -> Reply; {streamcontent_from_pid,_,_}=Reply -> Reply; {websocket,_,_}=Reply -> Reply; ok -> handle_out_reply_l(T, LineNo, YawsFile, UT, ARG, Res); RetVal -> %% XXX: if RetVal == #arg{}, replace ARG in recursion ? handle_out_reply_l(T, LineNo, YawsFile, UT, ARG, RetVal) end; handle_out_reply_l([], _LineNo, _YawsFile, _UT, _ARG, Res) -> Res. count_trailing_spaces() -> case get(acc_content) of undefined -> 0; discard -> 0; List -> Binary = first_binary(List), yaws_exhtml:count_trailing_spaces(Binary) end. first_binary([Binary|_]) when is_binary(Binary) -> Binary; first_binary([List|_Rest]) when is_list(List) -> first_binary(List). %% fast server side include with macrolike variable bindings expansion %% ssi(File, Delimiter, Bindings) -> ssi(File, Delimiter, Bindings, get(yaws_ut), get(yaws_arg), get (sc)). ssi(File, Delimiter, Bindings, UT, ARG) -> ssi(File, Delimiter, Bindings, UT, ARG, get(sc)). ssi(File, Delimiter, Bindings, UT, ARG, SC) -> Dir = UT#urltype.dir, %%Dir here should be equiv to arg.prepath Docroot = ARG#arg.docroot, VirtualDir = ARG#arg.docroot_mount, %%JMN - line below looks suspicious, why are we not keying on %% {ssi, File, Dir} ??? %%Surely a name like header.inc may be present in various parts of the %% hierarchy so Dir should form part of key. Key = {ssi, File, Delimiter}, %%!todo - review rel_path & abs_path - define & document behaviour.. %% or remove them. FullPath = case File of {rel_path, FileName} -> [Docroot, [$/|Dir],[$/|FileName]]; {abs_path, FileName} -> [Docroot, [$/|FileName]]; [$/|_] -> %%absolute path - need to determine Docroot and any Vdir %% that might apply {Vdir, DR} = vdirpath(SC, ARG, File), construct_fullpath(DR, File, Vdir); _ -> %%relative to the Docroot and VirtualDir that correspond %% to the request. construct_fullpath(Docroot, lists:flatten([Dir, [$/|File]]), VirtualDir) end, Mtime = path_to_mtime(FullPath), case ets:lookup(SC#sconf.ets, Key) of [{_, Parts, Mtime}] -> case (catch expand_parts(Parts, Bindings, [])) of {'EXIT', ErrStr} -> {error, ErrStr}; Value -> Value end; _ -> case prim_file:read_file(FullPath) of {ok, Bin} -> D =delim_split_file(Delimiter,binary_to_list(Bin),data,[]), ets:insert(SC#sconf.ets,{Key,D, Mtime}), ssi(File, Delimiter, Bindings, UT, ARG, SC); {error, _} when SC#sconf.xtra_docroots /= [] -> SC2 = SC#sconf{docroot = hd(SC#sconf.xtra_docroots), xtra_docroots = tl(SC#sconf.xtra_docroots)}, ARG2 = ARG#arg{ docroot = hd(SC#sconf.xtra_docroots), docroot_mount = "/" }, ssi(File, Delimiter, Bindings, UT, ARG2, SC2); {error, Rsn} -> error_logger:format("Failed to read/ssi file ~p~n", [FullPath]), {error,Rsn} end end. path_to_mtime(FullPath) -> case prim_file:read_file_info(FullPath) of {ok, FI} -> mtime(FI); Err -> Err end. expand_parts([{data, D} |T], Bs, Ack) -> expand_parts(T, Bs, [D|Ack]); expand_parts([{var, V} |T] , Bs, Ack) -> case lists:keysearch(V, 1, Bs) of {value, {_, {ehtml, E}}} -> case safe_ehtml_expand(E) of {ok, Val} -> expand_parts(T, Bs, [Val|Ack]); {error, ErrStr} -> erlang:error(ErrStr) end; {value, {_, Val}} -> expand_parts(T, Bs, [Val|Ack]); false -> case get({binding,V}) of undefined -> expand_parts(T, Bs, Ack); Valb -> expand_parts(T, Bs, [Valb|Ack]) end end; expand_parts([], _,Ack) -> lists:reverse(Ack). delim_split_file([], Data, _, _Ack) -> [{data, Data}]; delim_split_file(Del, Data, State, Ack) -> case delim_split(Del, Del, Data, [], []) of {H, []} when State == data -> %% Ok, last chunk lists:reverse([{data, list_to_binary(H)} | Ack]); {H, T} when State == data -> delim_split_file(Del, T, var, [{data, list_to_binary(H)}|Ack]); {H, []} when State == var -> lists:reverse([{var, H} | Ack]); {H, T} when State == var -> delim_split_file(Del, T, data, [{var, H}|Ack]) end. delim_split([H|T], Odel, [H|T1], Ack, DAcc) -> delim_split(T,Odel,T1,Ack, [H|DAcc]); delim_split([], _Odel, T, Ack, _DAcc) -> {lists:reverse(Ack),T}; delim_split([H|_T],Odel, [H1|T1], Ack, []) when H /= H1 -> delim_split(Odel, Odel, T1, [H1|Ack], []); delim_split([H|_T],Odel, [H1|T1], Ack, DAcc) when H /= H1 -> delim_split(Odel, Odel, T1, [H1|DAcc++Ack], []); delim_split(_,_,[],Ack,[]) -> {lists:reverse(Ack),[]}; delim_split(_,_,[],Ack,DAcc) -> {lists:reverse(DAcc++Ack),[]}. %% Erlang yaws code crashed, display either the %% actual crash or a customized error message handle_crash(ARG, L) -> ?Debug("handle_crash(~p)~n", [L]), SC=get(sc), yaws:outh_set_status_code(500), case catch apply(SC#sconf.errormod_crash, crashmsg, [ARG, SC, L]) of {content,MimeType,Cont} -> yaws:outh_set_content_type(MimeType), accumulate_content(Cont), break; {html, Str} -> accumulate_content(Str), break; {ehtml, Term} -> case safe_ehtml_expand(Term) of {error, Reason} -> yaws:elog("~s", [Reason]), %% Aghhh, yet another user crash :-( T2 = [{h2, [], "Internal error"}, {hr}, {p, [], "Customized crash display code crashed !!!"}], accumulate_content(ehtml_expand(T2)), break; {ok, Out} -> accumulate_content(Out), break end; Other -> yaws:elog("Bad return value from errmod_crash ~n~p~n",[Other]), T2 = [{h2, [], "Internal error"}, {hr}, {p, [], "Customized crash display code returned bad val"}], accumulate_content(ehtml_expand(T2)), break end. %% Ret: true | false | {data, Data} decide_deflate(false, _, _, _, _, _, _) -> ?Debug("Compression not supported by the server~n", []), false; decide_deflate(_, _, _, _, _, identity, _) -> ?Debug("No compression: Encoding=identity~n", []), false; decide_deflate(_, _, _, _, _, deflate, _) -> ?Debug("Compression already handled: Encoding=deflate~n", []), false; decide_deflate(true, SC, Arg, Sz, Data, decide, Mode) -> DOpts = SC#sconf.deflate_options, if Mode == final andalso size(Data) == 0 -> ?Debug("No data to be compressed~n",[]), false; Mode == final andalso DOpts#deflate.min_compress_size /= nolimit andalso size(Data) < DOpts#deflate.min_compress_size -> ?Debug("Data too small to be compressed~n",[]), false; is_integer(Sz) andalso DOpts#deflate.min_compress_size /= nolimit andalso Sz < DOpts#deflate.min_compress_size -> ?Debug("Data too small to be compressed~n",[]), false; true -> Mime0 = yaws:outh_get_content_type(), [Mime1|_] = yaws:split_sep(Mime0, $;), %% Remove charset ?Debug("Check compression support: Mime-Type=~p~n", [Mime1]), case compressible_mime_type(Mime1, DOpts) of true -> case (Arg =:= undefined orelse yaws:accepts_gzip(Arg#arg.headers, Mime1)) of true when Mode =:= final -> ?Debug("Compress data~n", []), yaws:outh_set_content_encoding(deflate), {ok, DB} = yaws_zlib:gzip(Data, DOpts), {data, DB}; true -> %% Mode == stream | {file,_,_} ?Debug("Compress streamed data~n", []), yaws:outh_set_content_encoding(deflate), true; false -> ?Debug("Compression not supported by the client~n", []), yaws:outh_set_content_encoding(identity), false end; false -> ?Debug("~p is not compressible~n", [Mime1]), yaws:outh_set_content_encoding(identity), false end end. deliver_accumulated(Sock) -> case yaws:outh_get_content_encoding() of decide -> yaws:outh_set_content_encoding(identity); _ -> ok end, deliver_accumulated(undefined, Sock, undefined, final). %% Arg = #arg{} | undefined %% ContentLength = Int | undefined %% Mode = final | stream | {file, File, MTime} %% %% For Mode==final: (all content has been accumulated before calling %% deliver_accumulated) %% Result: can be ignored %% %% For Mode==stream: %% Result: opaque value to be threaded through %% send_streamcontent_chunk / end_streaming %% %% For Mode=={file,File,MTime}: %% Result: {gzfile, GzFile} is gzip_static option is enabled and if %% GzFile exists. Else, same result than for Mode==stream deliver_accumulated(Arg, Sock, ContentLength, Mode) -> %% See if we must close the connection receive {_From, suspend} -> yaws:outh_set_connection(true) after 0 -> ok end, Cont = case erase(acc_content) of undefined -> []; Cont2 -> Cont2 end, {Result, Data} = case Cont of discard -> yaws:outh_set_transfer_encoding_off(), {discard, []}; _ -> deflate_accumulated(Arg, iolist_to_binary(Cont), ContentLength, Mode) end, {StatusLine, Headers} = yaws:outh_serialize(), All = [StatusLine, Headers, crnl(), Data], yaws:gen_tcp_send(Sock, All), case yaws_trace:get_type(get(gc)) of http -> yaws_trace:write(from_server, [StatusLine, Headers]); traffic -> yaws_trace:write(from_server, All); undefined -> ok end, Result. deflate_accumulated(Arg, Content, ContentLength, Mode) -> case get(sc) of undefined -> {undefined, Content}; SC -> Enc = yaws:outh_get_content_encoding(), DOpts = SC#sconf.deflate_options, {Result, Data, Size} = case decide_deflate(?sc_has_deflate(SC), SC, Arg, ContentLength, Content, Enc, Mode) of {data, Bin} -> %% implies Mode==final {undefined, Bin, iolist_size(Bin)}; true when Mode == stream; DOpts#deflate.use_gzip_static == false -> Z = zlib:open(), {ok, Priv, Bin} = yaws_zlib:gzipDeflate(Z,yaws_zlib:gzipInit(Z,DOpts), Content,none), {{Z, Priv}, Bin, undefined}; true -> %% implies Mode=={file,_,_} and use_gzip_static==true {file, File, MTime} = Mode, GzFile = File++".gz", case prim_file:read_file_info(GzFile) of {ok, FI} when FI#file_info.type == regular, FI#file_info.mtime >= MTime -> {{gzfile, GzFile}, <<>>, FI#file_info.size}; _ -> Z = zlib:open(), {ok, Priv, Bin} = yaws_zlib:gzipDeflate(Z,yaws_zlib:gzipInit(Z,DOpts), Content,none), {{Z, Priv}, Bin, undefined} end; false when Mode == final -> {undefined, Content, iolist_size(Content)}; false -> %% implies Mode=stream | {file,_,_} {undefined, Content, ContentLength} end, case Size of undefined -> yaws:outh_fix_doclose(); _ -> yaws:accumulate_header({content_length, Size}) end, case Mode of final -> {Result, Data}; _ -> case make_chunk(Data) of empty -> {Result, []}; {S, Chunk} -> yaws:outh_inc_act_contlen(S), {Result, Chunk} end end end. get_more_post_data(CliSock, PPS, ARG) -> SC = get(sc), N = SC#sconf.partial_post_size, case (ARG#arg.headers)#headers.content_length of undefined -> case yaws:to_lower((ARG#arg.headers)#headers.transfer_encoding) of "chunked" -> get_chunked_client_data(CliSock, yaws:is_ssl(SC)); _ -> <<>> end; Len -> Int_len = list_to_integer(Len), if N + PPS < Int_len -> Bin = get_client_data(CliSock, N, yaws:is_ssl(SC)), {partial, Bin}; true -> get_client_data(CliSock, Int_len - PPS, yaws:is_ssl(SC)) end end. ut_read(UT) -> ?Debug("ut_read() UT.fullpath = ~p~n", [UT#urltype.fullpath]), CE = yaws:outh_get_content_encoding(), if (CE =:= identity) andalso is_binary(UT#urltype.data) -> UT#urltype.data; CE =:= identity -> ?Debug("ut_read reading\n",[]), {ok, Bin} = file:read_file(UT#urltype.fullpath), ?Debug("ut_read read ~p\n",[size(Bin)]), Bin; (CE =:= decide) andalso is_binary(UT#urltype.deflate) -> ?Debug("ut_read using deflated binary of size ~p~n", [size(UT#urltype.deflate)]), yaws:outh_set_content_encoding(deflate), UT#urltype.deflate; CE =:= decide andalso is_binary(UT#urltype.data) -> UT#urltype.data; CE =:= decide -> ?Debug("ut_read reading\n",[]), {ok, Bin} = file:read_file(UT#urltype.fullpath), ?Debug("ut_read read ~p\n",[size(Bin)]), Bin; CE =:= deflate -> ?Debug("ut_read using deflated binary of size ~p~n", [size(UT#urltype.deflate)]), UT#urltype.deflate end. parse_range(L, Tot) -> case catch parse_range_throw(L, Tot) of {'EXIT', _} -> error; R -> R end. parse_range_throw(L, Tot) -> case lists:splitwith(fun(C)->C /= $- end, L) of {FromS, [$-|ToS]} -> case FromS of [] -> case list_to_integer(ToS) of I when Tot >= I, I>0 -> {fromto, Tot-I, Tot-1, Tot} end; _ -> case list_to_integer(FromS) of From when From>=0, From < Tot -> case ToS of [] -> {fromto, From, Tot-1, Tot}; _ -> case list_to_integer(ToS) of To when To {fromto, From, To, Tot}; _ -> {fromto, From, Tot-1, Tot} end end end end end. %% This is not exactly what the RFC describes, but we do not want to %% deal with multipart/byteranges. unite_ranges(all, _) -> all; unite_ranges(error, R) -> R; unite_ranges(_, all) -> all; unite_ranges(R, error) -> R; unite_ranges({fromto, F0, T0, Tot},{fromto,F1,T1, Tot}) -> {fromto, if F0 >= F1 -> F1; true -> F0 end, if T0 >= T1 -> T0; true -> T1 end, Tot }. %% ret: all | error | {fromto, From, To, Tot} requested_range(RangeHeader, TotalSize) -> case yaws:split_sep(RangeHeader, $,) of ["bytes="++H|T] -> lists:foldl(fun(L, R)-> unite_ranges(parse_range(L, TotalSize), R) end, parse_range(H, TotalSize), T); _ -> all end. deliver_file(CliSock, Req, UT, Range) -> if is_binary(UT#urltype.data) -> %% cached deliver_small_file(CliSock, Req, UT, Range); true -> deliver_large_file(CliSock, Req, UT, Range) end. deliver_small_file(CliSock, _Req, UT, Range) -> Bin0 = ut_read(UT), Bin = case Range of all -> Bin0; {fromto, From, To, _Tot} -> Length = To - From + 1, <<_:From/binary, Bin1:Length/binary, _/binary>> = Bin0, Bin1 end, accumulate_content(Bin), deliver_accumulated(CliSock), done_or_continue(). deliver_large_file(CliSock, _Req, UT, Range) -> Sz = case Range of all -> (UT#urltype.finfo)#file_info.size; {fromto, From, To, _Tot} -> yaws:outh_set_content_encoding(identity), (To - From + 1) end, Mode = {file, UT#urltype.fullpath, mtime(UT#urltype.finfo)}, case deliver_accumulated(undefined, CliSock, Sz, Mode) of discard -> ok; Priv -> send_file(CliSock, UT#urltype.fullpath, Range, Priv) end, done_or_continue(). send_file(CliSock, Path, all, undefined) when is_port(CliSock) -> ?Debug("send_file(~p,~p,no ...)~n", [CliSock, Path]), Size = yaws_sendfile:send(CliSock, Path), yaws_stats:sent(Size); send_file(CliSock, Path, all, undefined) -> ?Debug("send_file(~p,~p,no ...)~n", [CliSock, Path]), {ok, Fd} = file:open(Path, [raw, binary, read]), send_file(CliSock, Fd, undefined); send_file(CliSock, _, all, {gzfile, GzFile}) when is_port(CliSock) -> ?Debug("send_file(~p,~p, ...)~n", [CliSock, GzFile]), Size = yaws_sendfile:send(CliSock, GzFile), yaws_stats:sent(Size); send_file(CliSock, _, all, {gzfile, GzFile}) -> ?Debug("send_file(~p,~p, ...)~n", [CliSock, GzFile]), {ok, Fd} = file:open(GzFile, [raw, binary, read]), send_file(CliSock, Fd, undefined); send_file(CliSock, Path, all, Priv) -> ?Debug("send_file(~p,~p, ...)~n", [CliSock, Path]), {ok, Fd} = file:open(Path, [raw, binary, read]), send_file(CliSock, Fd, Priv); send_file(CliSock, Path, {fromto, From, To, _Tot}, _) when is_port(CliSock) -> Size = yaws_sendfile:send(CliSock, Path, From, (To-From+1)), yaws_stats:sent(Size); send_file(CliSock, Path, {fromto, From, To, _Tot}, _) -> {ok, Fd} = file:open(Path, [raw, binary, read]), file:position(Fd, {bof, From}), send_file_range(CliSock, Fd, To - From + 1). send_file(CliSock, Fd, Priv) -> ?Debug("send_file(~p,~p, ...)~n", [CliSock, Fd]), case file:read(Fd, (get(gc))#gconf.large_file_chunk_size) of {ok, Bin} -> Priv1 = send_streamcontent_chunk(Priv, CliSock, Bin), send_file(CliSock, Fd, Priv1); eof -> file:close(Fd), end_streaming(Priv, CliSock) end. send_file_range(CliSock, Fd, Len) when Len > 0 -> {ok, Bin} = file:read(Fd, case (get(gc))#gconf.large_file_chunk_size of S when S < Len -> S; _ -> Len end ), send_streamcontent_chunk(undefined, CliSock, Bin), send_file_range(CliSock, Fd, Len - size(Bin)); send_file_range(CliSock, Fd, 0) -> file:close(Fd), end_streaming(undefined, CliSock). crnl() -> "\r\n". -ifdef(HAVE_ERLANG_NOW). now_secs() -> {M,S,_}=now(), (M*1000000)+S. -else. now_secs() -> {M,S,_} = erlang:timestamp(), (M*1000000)+S. -endif. %% a file cache, url_type(GetPath, ArgDocroot, VirtualDir) -> SC=get(sc), GC=get(gc), E = SC#sconf.ets, %% In reentrant call, the cache can be disabled. It could be useful in case %% of "proxy" appmod. NoCache = case get(is_reentrant_request) of true -> case get(page_options) of undefined -> false; Opts -> proplists:get_bool(disable_cache, Opts) end; _ -> false end, case ets:lookup(E, {url, GetPath}) of [] -> UT = do_url_type(SC, GetPath, ArgDocroot, VirtualDir), ?TC([{record, UT, urltype}]), ?Debug("UT=~s\n", [?format_record(UT, urltype)]), if NoCache -> ?Debug("Cache disabled\n", []), UT; true -> CF = cache_file(SC, GC, GetPath, UT), ?Debug("CF=~s\n", [?format_record(CF, urltype)]), CF end; [{_, When, UT}] -> N = now_secs(), Refresh = GC#gconf.cache_refresh_secs, if ((N-When) >= Refresh) -> ?Debug("Timed out entry for ~s ~p~n", [GetPath, {When, N}]), %% more than 30 secs old entry UT2 = do_url_type(SC, GetPath, ArgDocroot, VirtualDir), case file_changed(UT, UT2) of true -> ?Debug("Recaching~n", []), ets:delete(E, {url, GetPath}), ets:delete(E, {urlc, GetPath}), ets:update_counter(E, num_files, -1), ets:update_counter(E, num_bytes, -cache_size(UT)), cache_file(SC, GC, GetPath, UT2); false -> ?Debug("Using unchanged cached version~n", []), (catch ets:update_counter(E, {urlc, GetPath}, 1)), UT end; true -> ?Debug("Serve page from cache ~p", [{When , N, N-When}]), (catch ets:update_counter(E, {urlc, GetPath}, 1)), UT end end. file_changed(UT1, UT2) -> case {UT1#urltype.type, UT2#urltype.type} of {T, T} when T==yaws; T==regular-> F1 = UT1#urltype.finfo, F2 = UT2#urltype.finfo, {F1#file_info.inode, F1#file_info.mtime} /= {F2#file_info.inode, F2#file_info.mtime}; _ -> true % don't care too much end. cache_size(UT) when is_binary(UT#urltype.deflate), is_binary(UT#urltype.data) -> size(UT#urltype.deflate) + size(UT#urltype.data); cache_size(UT) when is_binary(UT#urltype.data) -> size(UT#urltype.data); cache_size(_UT) -> 0. cache_file(_SC, GC, _Path, UT) when GC#gconf.max_num_cached_files == 0; GC#gconf.max_num_cached_bytes == 0; GC#gconf.max_size_cached_file == 0 -> UT; cache_file(SC, GC, Path, UT) when ((UT#urltype.type == regular) or ((UT#urltype.type == yaws) and (UT#urltype.pathinfo == undefined))) -> E = SC#sconf.ets, [{num_files, N}] = ets:lookup(E, num_files), [{num_bytes, B}] = ets:lookup(E, num_bytes), FI = UT#urltype.finfo, ?Debug("FI=~s\n", [?format_record(FI, file_info)]), if N + 1 > GC#gconf.max_num_cached_files -> error_logger:info_msg("Max NUM cached files reached for server ~p", [SC#sconf.servername]), cleanup_cache(E, num), cache_file(SC, GC, Path, UT); FI#file_info.size < GC#gconf.max_size_cached_file, FI#file_info.size < GC#gconf.max_num_cached_bytes, B + FI#file_info.size > GC#gconf.max_num_cached_bytes -> error_logger:info_msg("Max size cached bytes reached for server ~p", [SC#sconf.servername]), cleanup_cache(E, size), cache_file(SC, GC, Path, UT); true -> ?Debug("Check file size\n",[]), if FI#file_info.size > GC#gconf.max_size_cached_file; FI#file_info.size > GC#gconf.max_num_cached_bytes -> ?Debug("Too large\n",[]), UT; true -> ?Debug("File fits\n",[]), {ok, Bin} = prim_file:read_file(UT#urltype.fullpath), DOpts = SC#sconf.deflate_options, Deflated = if size(Bin) == 0 -> undefined; DOpts#deflate.min_compress_size /= nolimit, size(Bin) < DOpts#deflate.min_compress_size -> undefined; UT#urltype.deflate /= dynamic -> undefined; true -> {ok, DBL} = yaws_zlib:gzip(Bin, DOpts), DB = list_to_binary(DBL), if (10 * size(DB)) < (9 * size(Bin)) -> ?Debug("storing deflated version " "of ~p~n",[UT#urltype.fullpath]), DB; true -> undefined end end, UT2 = UT#urltype{data = Bin, deflate = Deflated}, ets:insert(E, {{url, Path}, now_secs(), UT2}), ets:insert(E, {{urlc, Path}, 1}), ets:update_counter(E, num_files, 1), ets:update_counter(E, num_bytes, cache_size(UT2)), UT2 end end; cache_file(_SC, _GC, _Path, UT) -> UT. %% FIXME, should not wipe entire ets table this way cleanup_cache(E, size) -> %% remove the largest files with the least hit count (urlc) ?Debug("Clearing yaws internal content " "cache, size overflow",[]), clear_ets(E); cleanup_cache(E, num) -> ?Debug("Clearing yaws internal content " "cache, num overflow",[]), clear_ets(E). %% Clear everything, but *not* the Yaws specs, because otherwise we %% would have orphan modules loaded. clear_ets(E) -> ets:match_delete(E, {{url, '_'}, '_', '_'}), ets:match_delete(E, {{urlc, '_'}, '_', '_'}), ets:insert(E, {num_files, 0}), ets:insert(E, {num_bytes, 0}). %% return #urltype record do_url_type(SC, GetPath, ArgDocroot, VirtualDir) -> ?Debug("do_url_type SC=~s~nGetPath=~p~nVirtualDir=~p~n", [?format_record(SC,sconf), GetPath,VirtualDir]), case GetPath of _ when ?sc_has_dav(SC) -> {Comps, RevFile} = comp_split(GetPath), {_Type, Mime} = suffix_type(SC, RevFile), FullPath = construct_fullpath(ArgDocroot, GetPath, VirtualDir), %%!!WARNING!!! %%!TODO - review & test! %%Implications of vdirs on DAV have not yet been fully %% considered by author of vdir support (JMN) #urltype{type = dav, dir = conc_path(Comps), getpath = GetPath, path = GetPath, fullpath = FullPath, mime = Mime}; "/" -> %% special case case lists:keysearch("/", 1, SC#sconf.appmods) of {value, AppmodDef} -> %% Remove appmod for this request to avoid an infinte loop %% in case of a reentrant call put(sc, SC#sconf{appmods=lists:delete( AppmodDef, SC#sconf.appmods )}), %% AppmodDef can be either a 2-tuple or 3-tuple depending %% on whether there are exclude paths present. We want %% only the second element of the tuple in either case. Mod = element(2, AppmodDef), #urltype{type = appmod, data = {Mod, []}, dir = "", path = "", fullpath = ArgDocroot}; _ -> maybe_return_dir(ArgDocroot, GetPath, VirtualDir) end; [$/, $~ |Tail] -> ret_user_dir(Tail); _ -> FullPath = construct_fullpath(ArgDocroot, GetPath, VirtualDir), {Comps, RevFile} = comp_split(GetPath), ?Debug("Comps = ~p RevFile = ~p~n",[Comps, RevFile]), RequestSegs = string:tokens(GetPath,"/"), case active_appmod(SC#sconf.appmods, RequestSegs) of false -> ?Debug("FullPath = ~p~n", [FullPath]), case prim_file:read_file_info(FullPath) of {ok, FI} when FI#file_info.type == regular -> {Type, Mime} = suffix_type(SC, RevFile), #urltype{type=Type, finfo=FI, deflate=deflate_q(?sc_has_deflate(SC), SC, Type, Mime), dir = conc_path(Comps), path = GetPath, getpath = GetPath, fullpath = FullPath, mime=Mime}; {ok, FI} when FI#file_info.type == directory -> case RevFile of [] -> maybe_return_dir(ArgDocroot, GetPath, VirtualDir); _ -> %%Presence of RevFile indicates dir url %% had no trailing / #urltype{ type = redir, path = [GetPath, "/"]} end; _Err -> %% non-optimal, on purpose maybe_return_path_info(SC, Comps, RevFile, ArgDocroot, VirtualDir) end; {ok, {Mount, Mod}} -> %% Remove appmod for this request to avoid an infinte loop %% in case of a reentrant call put(sc, SC#sconf{appmods=lists:keydelete( Mount, 1, SC#sconf.appmods )}), %%active_appmod found the most specific appmod for this %% request path %% - now we need to determine the prepath & path_info MountSegs = string:tokens(Mount,"/"), case Mount of [$/] -> %%'root' appmod PostSegments = lists:sublist(RequestSegs,1, length(RequestSegs)), Prepath = ""; [$/|_] -> %%'anchored' appmod mount. PreSegments = lists:sublist(RequestSegs, length(MountSegs)-1), PostSegments = lists:sublist(RequestSegs, length(MountSegs)+1, length(RequestSegs)), Prepath = case PreSegments of "" -> "/"; _ -> "/" ++ yaws:join_sep(PreSegments,"/") ++ "/" end; _ -> %%'floating' appmod mount. {PreSegments,PostSegments} = split_at_segment(Mount,RequestSegs,[]), Prepath = case PreSegments of "" -> "/"; _ -> "/" ++ yaws:join_sep(PreSegments,"/") ++ "/" end end, PathI = case PostSegments of [] -> ""; _ -> "/" ++ yaws:join_sep(PostSegments,"/") end, %%absence of RevFile tells us there was a trailing slash. PathInf = case RevFile of [] -> PathI ++ "/"; _ -> PathI end, PathInfo = case PathInf of "" -> undefined; _ -> PathInf end, Path = case MountSegs of [] -> %%'root' appmod Prepath; _ -> Prepath ++ tl(MountSegs) end, #urltype{ type = appmod, data = {Mod, PathInfo}, dir = Prepath, path = Path, fullpath = FullPath, pathinfo = PathInfo } end end. %% comp_split/1 - split a path around "/" returning final segment as %% reversed string. %% return {Comps, RevPart} where Comps is a (possibly empty) list of path %% components - always with trailing "/" %% revPart is the final segment in reverse and has no "/". %% e.g split( "/test/etc/index.html",[],[]) -> %% {["/test/", "etc/"], "lmth.xedni"} %% revPart is useful in this form for looking up the file extension's mime-type. %% %% Terminology note to devs: reserve the word 'comp' to refer to a single %% fragment of a path that we know has %% a trailing slash. If you're dealing just with the part between slashes - %% consider using the term 'segment' instead. %% e.g "x/" "/" are all valid 'comps' %% "/x" "/x/y/" "x" are not. %% comp_split(Path) -> do_comp_split(Path,[],[]). %%when Part /= [] do_comp_split([$/|Tail], Comps, Part) -> NewComp = lists:reverse([$/|Part]), do_comp_split(Tail, [NewComp | Comps], []); do_comp_split([H|T], Comps, Part) -> do_comp_split(T, Comps, [H|Part]); do_comp_split([], Comps, Part) -> {lists:reverse(Comps), Part}. %%active_appmod/2 %%find longest appmod match for request. (ie 'most specific' appmod) %% - conceptually similar to the vdirpath scanning - but must also support %% 'floating appmods' i.e an appmod specified as where %% 'path' has no leading slash. %% %% a 'floating' appmod is not tied to a specific point in the URI structure %% e.g for the configuration entry %% the requests /docs/stuff/myapp/etc & /otherpath/myapp will both %% trigger the myappAppmod module. %% whereas for the configuration entry %% the request /otherpath/myapp will not trigger the appmod. %% active_appmod([], _RequestSegs) -> false; active_appmod(AppMods, RequestSegs) -> %%!todo - review/test performance (e.g 'fun' calls are slower than a %% call to a local func - replace?) %%Accumulator is of form {RequestSegs, {AppmodMountPoint,Mod}} Matched = lists:foldl( fun(Pair,Acc) -> {Mount, Mod, Excludes} = case Pair of {X, Y} -> {X, Y, []}; {X,Y,Z} -> {X,Y,Z} end, {ReqSegs, {LongestSoFar, _}} = Acc, MountSegs = string:tokens(Mount,"/"), case {is_excluded(ReqSegs, Excludes) , lists:prefix(MountSegs,ReqSegs)} of {true, _} -> Acc; {false, true} -> case LongestSoFar of [$/|_] -> %%simple comparison of string length %% (as opposed to number of segments) %% should be ok here. if length(Mount) > length(LongestSoFar) -> {ReqSegs, {Mount, Mod}}; true -> Acc end; _ -> %%existing match is 'floating' - %% we trump it. {ReqSegs, {Mount, Mod}} end; {false, false} -> case LongestSoFar of [$/|_] -> %%There is already a match for an %% 'anchored' (ie absolute path) %% mount point. %% floating appmod can't override. Acc; _ -> %%check for 'floating' match case lists:member(Mount, ReqSegs) of true -> %%!todo - review & document. %%latest 'floating' match wins %% if multiple match? %% (order in config vs position %% in request URI ?) {ReqSegs, {Mount, Mod}}; false -> Acc end end end end, {RequestSegs, {"",""}}, AppMods), case Matched of {_RequestSegs, {"",""}} -> %%no appmod corresponding specifically to this http_request.path false; {_RequestSegs, {Mount, Mod}} -> {ok, {Mount, Mod}} end . is_excluded(_, []) -> false; is_excluded(RequestSegs, [ExcludeSegs|T]) -> case lists:prefix(ExcludeSegs, RequestSegs) of true -> true; false -> is_excluded(RequestSegs, T) end. %%split a list of segments into 2 lists either side of element matching Seg. %%(no elements contain slashes) split_at_segment(_, [], _Acc) -> false; split_at_segment(Seg,[Seg|Tail],Acc) -> {lists:reverse(Acc),Tail}; split_at_segment(Seg,[H|Tail],Acc) -> split_at_segment(Seg, Tail, [H|Acc]). %% construct_fullpath %% %%preconditions: %% - DR, GetPath, VirtualDir already validated &/or normalized %% - VirtualDir is empty string, or a prefix of GetPath of the form "/path/" %% where path may also contain "/" %% - DocRoot is a valid physical path to a directory, with no trailing "/" %% %%i.e this is an inner function, so no sanity checks here. %% construct_fullpath(undefined,_,_) -> undefined; construct_fullpath(DocRoot,GetPath,VirtualDir) -> case VirtualDir of [] -> DocRoot ++ GetPath; _ -> %%trim the virtual base off the GET request path before appending %% to DocRoot. %%(leaving one "/" - therefore don't add 1 to length) DocRoot ++ string:substr(GetPath,length(VirtualDir)) end . %%preconditions: %% - see 'construct_fullpath' %% try_index_file(_FullPath, _GetPath, []) -> noindex; try_index_file(FullPath, GetPath, [[$/|_]=Idx|Rest]) -> case (GetPath =:= Idx orelse GetPath =:= Idx++"/") of true -> try_index_file(FullPath, GetPath, Rest); false -> {redir, Idx} end; try_index_file(FullPath, GetPath, [Idx|Rest]) -> case prim_file:read_file_info([FullPath, Idx]) of {ok, FI} when FI#file_info.type == regular -> {index, Idx}; _ -> try_index_file(FullPath, GetPath, Rest) end. maybe_return_dir(DR, GetPath,VirtualDir) -> SC = get(sc), FullPath = construct_fullpath(DR, GetPath, VirtualDir), case try_index_file(FullPath, GetPath, SC#sconf.index_files) of {index, Idx} -> do_url_type(SC, GetPath ++ Idx, DR, VirtualDir); {redir, NewPath} -> #urltype{type=redir, path=NewPath}; noindex -> case file:list_dir(FullPath) of {ok, List} -> #urltype{type = directory, fullpath = FullPath, dir = GetPath, data = List -- [".yaws_auth"]}; _Err -> #urltype{type=error} end end. maybe_return_path_info(SC, Comps, RevFile, DR, VirtualDir) -> case path_info_split(SC, Comps, {DR, VirtualDir}) of {not_a_script, error} -> %%can we use urltype.data to return more info? %% - logging? #urltype{type=error}; {ok, FI, FullPath, HeadComps, File, TrailComps, Type, Mime} -> %%'File' is the only comp that has been returned %% without trailing "/" {Type2, Mime2} = case member(Type, SC#sconf.allowed_scripts) of true -> {Type, Mime}; false -> %%!todo review. %%Should we really be returning the file as text/plain %% when there is pathinfo present? %%Perhaps a 403 error would be more appropriate. {regular, "text/plain"} end, ?Debug("'script-selection' FullPath= ~p~n Mime=~p~n", [FullPath, Mime2]), Trail = conc_path([ "/" ] ++ TrailComps ++ [ lists:reverse(RevFile) ]), #urltype{type = Type2, finfo=FI, deflate=deflate_q(?sc_has_deflate(SC), SC, Type, Mime), dir = conc_path(HeadComps), path = conc_path(HeadComps ++ [File]), fullpath = FullPath, pathinfo = Trail, getpath = case HeadComps of [] -> [$/|File]; [_|_] -> conc_path(HeadComps ++ [File]) end, mime = Mime2} end. %%scan a list of 'comps' of form "pathsegment/" %% (trailing slash always present) %% - looking for the rightmost dotted component that corresponds to a script %% file. %% By the time path_info_split is called - the fullpath has already been tested %% and found not to be a file or directory %% %% Limitation: we don't support a script file without a dot. %% - otherwise we'd have to hit the filesystem for too many path components %% to see if they exist & are an executable file. %% %% !!todo - review (potential security issue). %% Right-to-left scanning should stop once we reach a 'document root mount %% point', otherwise the Docroot that has been determined based on the full %% request path becomes invalid! %% path_info_split(SC, Comps,DR_Vdir) -> path_info_split(SC, lists:reverse(Comps), DR_Vdir, []). path_info_split(SC, [H|T], {DR, VirtualDir}, AccPathInfo) -> [$/|RevPath] = lists:reverse(H), case suffix_from_rev(RevPath) of [] -> % shortcut clause, not necessary path_info_split(SC, T, {DR, VirtualDir}, [H|AccPathInfo]); Suff -> {Type, Mime} = mime_types:t(SC, Suff), case Type of regular -> %%Don't hit the filesystem to test components that %%'mime_types' indicates can't possibly be scripts path_info_split(SC, T, {DR, VirtualDir}, [H|AccPathInfo]); X -> %%We may still be in the 'PATH_INFO' section %%Test to see if it really is a script TestPath = lists:flatten(lists:reverse(T)), FullPath = construct_fullpath(DR, TestPath, VirtualDir) ++ string:strip(H,right,$/), ?Debug("Testing for script at: ~p~n", [FullPath]), case prim_file:read_file_info(FullPath) of {ok, FI} when FI#file_info.type == regular -> {ok, FI, FullPath, lists:reverse(T), string:strip(H,right,$/), AccPathInfo, X, Mime}; {ok, FI} when FI#file_info.type == directory -> %%just a case of a bad path starting at this point. {not_a_script, error}; _Err -> %%just looked like a script - keep going. path_info_split(SC, T, {DR, VirtualDir}, [H|AccPathInfo]) end end end; path_info_split(_SC, [], _DR_Vdir, _Acc) -> {not_a_script, error}. suffix_from_rev(R) -> suffix_from_rev(R, []). suffix_from_rev([$.|_], A) -> A; suffix_from_rev([C|T], A) -> suffix_from_rev(T, [C|A]); suffix_from_rev([], _A) -> []. %%conc_path %% - single-level concatenatenation of a list of path components which %% already contain slashes. %% tests suggest it's significantly faster than lists:flatten or lists:concat %% & marginally faster than lists:append %% (for paths of 3 or more segments anyway) %% tested with various fairly short path lists - see src/benchmarks folder %% %%Original conc_path([]) -> []; conc_path([H|T]) -> H ++ conc_path(T). %% tail-recursive version slower for longer paths according to bench.erl %% (mainly because we need to do 'Acc ++ H' rather than 'H ++ Acc') %% Tail recursion not very useful here anyway as we're %% dealing with short strings. %%conc_path2([]) -> %% []; %%conc_path2([H|T]) -> %% cpath(T,H). %%cpath([],Acc) -> %% Acc; %%cpath([H|[]],Acc) -> %% H ++ Acc; %%cpath([H|T],Acc) -> %% cpath(T,Acc ++ H). %% ret_app_mod(Path, Mod, PrePath) -> %% #urltype{type = appmod, %% data = {Mod, Path}, %% path = PrePath}. %% http://a.b.c/~user URLs ret_user_dir(Upath) -> ?Debug("ret_user_dir ~p~n", [Upath]), SC = get(sc), if ?sc_has_tilde_expand(SC) -> case parse_user_path(SC#sconf.docroot, Upath, []) of {ok, User, Path} -> %% FIXME doesn't work if passwd contains :: %% also this is unix only %% and it ain't the fastest code around. case catch yaws:user_to_home(User) of {'EXIT', _} -> #urltype{type=error}; Home -> DR2 = Home ++ "/public_html/", SC2 = SC#sconf{ allowed_scripts = SC#sconf.tilde_allowed_scripts, docroot=DR2}, put(sc, SC2), %% !todo - review interactions between Virtual %% Dirs & Home Dir paths. %% VirtualDir hardcoded empty is not %% nice behaviour - %% a rewrite mod author may reasonably expect to %% be able to have influence here. redir_user(do_url_type(SC2, Path, DR2,""), User) %% recurse end; {redir_dir, User} -> #urltype {type = redir, path = ["/~", User, "/"]} end; true -> #urltype{type=error} end. redir_user(UT, User) -> case UT#urltype.type of redir -> UT#urltype{path = ["/~", User, UT#urltype.path]}; _ -> UT end. parse_user_path(_DR, [], User) -> {redir_dir, reverse(User)}; parse_user_path(_DR, [$/], User) -> {ok, reverse(User), [$/]}; parse_user_path(_DR, [$/|Tail], User) -> {ok, reverse(User), [$/|Tail]}; parse_user_path(DR, [H|T], User) -> parse_user_path(DR, T, [H|User]). deflate_q(true, SC, regular, Mime0) -> [Mime1|_] = yaws:split_sep(Mime0, $;), %% Remove charset case compressible_mime_type(Mime1, SC#sconf.deflate_options) of true -> dynamic; false -> undefined end; deflate_q(_, _, _, _) -> undefined. suffix_type(SC, L) -> case mime_types:revt(SC, yaws:upto_char($., L)) of {regular, _Ext, Mime} -> {regular, Mime}; {X, _Ext, Mime} -> case member(X, SC#sconf.allowed_scripts) of true -> {X, Mime}; false -> {regular, mime_types:default_type(SC)} end end. compressible_mime_type(Mime, #deflate{mime_types=MimeTypes}) -> case yaws:split_sep(Mime, $/) of [Type, SubType] -> compressible_mime_type(Mime,Type,SubType,MimeTypes); _ -> false end. compressible_mime_type(_, _, _, all) -> true; compressible_mime_type(_, _, _, []) -> false; compressible_mime_type(_, Type, _, [{Type, all}|_]) -> true; compressible_mime_type(_, Type, SubType, [{Type, SubType}|_]) -> true; compressible_mime_type(Mime, _, _, [Mime|_]) -> true; compressible_mime_type(Mime, Type, SubType, [_|Rest]) -> compressible_mime_type(Mime, Type, SubType, Rest). flush(Sock, Sz, TransferEncoding) -> flush(Sock, 0, Sz, TransferEncoding). flush(Sock, Pos, undefined, "chunked") -> SC = get(sc), case get_chunked_client_data(Sock, yaws:is_ssl(SC)) of {partial, Bin} -> flush(Sock, Pos+size(Bin), undefined, "chunked"); _ -> Pos end; flush(_Sock, Pos, undefined, _) -> Pos; flush(Sock, Pos, Sz, TE) when is_list(Sz) -> flush(Sock, Pos, strip_list_to_integer(Sz), TE); flush(Sock, Pos, Sz, _) -> SC = get(sc), flush(Sock, Pos, Sz, yaws:is_ssl(SC), SC#sconf.partial_post_size). flush(_Sock, Sz, Sz, _SSL, _PPS) -> Sz; flush(Sock, Pos, Sz, SSL, PPS) -> case yaws:do_recv(Sock, erlang:min(Sz - Pos, PPS), SSL) of {ok, Bin} -> flush(Sock, Pos + size(Bin), Sz, SSL, PPS); _ -> Pos end. strip_list_to_integer(L) -> case catch list_to_integer(L) of {'EXIT', _} -> list_to_integer(string:strip(L, both)); Int -> Int end. mtime(F) -> F#file_info.mtime. runmod({ok, Mod}, GC) -> runmod2(GC, [Mod | GC#gconf.runmods]); runmod(_, GC) -> runmod2(GC, GC#gconf.runmods). runmod2(GC, Mods) -> foreach(fun(M) -> proc_lib:spawn(?MODULE, load_and_run, [M, ?gc_has_debug(GC)]) end, Mods). load_and_run(Mod, Debug) -> case code:ensure_loaded(Mod) of {module,Mod} when Debug == false -> Mod:start(); {module,Mod} when Debug == true -> error_logger:info_msg("sync call ~p:start ~n",[Mod]), Mod:start(); Error -> error_logger:error_msg("Loading '~w' failed, reason ~p~n", [Mod,Error]) end. safe_ehtml_expand(X) -> case (catch ehtml_expand(X)) of {'EXIT', R} -> {error, err_pre(R)}; Val -> {ok, Val} end. err_pre(R) -> io_lib:format("
 ~n~p~n 
~n", [R]). %% mappath/3 (virtual-path to physical-path) %% - this returns physical path a URI would map to, taking into consideration %% vdirs and assuming each path segment of the URI represents a folder %% (or maybe filename at end). %% ie it does not (and is not intended to) take into account 'script points' %% in the path. (cgi,fcgi,php,appmod etc) %% The result may not actually exists as a path. %% %% mappath/3 is analogous to the Microsoft ASP function Server.MapPath or %% the 'filename' array member of the result %% of the PHP function 'apache_lookup_uri'. %% mappath(SC, ARG, RequestPath) -> {VirtualDir, DR} = vdirpath(SC, ARG, RequestPath), PhysicalPath = construct_fullpath(DR, RequestPath, VirtualDir), %% Resultant path might not exist - that's not the concern of the %% 'mappath' function. PhysicalPath. %% vdirpath/3 %% find longest "vdir" match. %% (ie a 'document-root mount-point' -> DOCUMENT_ROOT_MOUNT) %% %% e.g if we have in our .conf: %% vdir = "/app/ /path1/somewhere" %% vdir = "/app/test/shared/ /path2/somewhere" %% %% A request path of /app/test/doc.html must be served from under %% /path1/somewhere %% /app/test/shared/doc.html will be served from under /path2/somewhere %% %% Also must be able to handle: %% vdir = "/somewhere/ /path3/has spaces/in path/docs" %% In this case, the 1st space separates the vdir from the physical path %% i.e subsequent spaces are part of the path. vdirpath(SC, ARG, RequestPath) -> Opaquelist = ARG#arg.opaque, %% !todo - move out of opaque. %% We don't want to scan all opaque entries each time %% - vdir directives should be pre-collated into a list somewhere. %% (own field in sconf record) RequestSegs = string:tokens(RequestPath,"/"), %% Accumulator is of form {RequestSegs,{VdirMountPoint,VdirPhysicalPath}} Matched = lists:foldl( fun(ListItem,Acc) -> case ListItem of {"vdir",Vmap} -> {ReqSegs,VdirSpec} = Acc, [Virt |PhysParts] = string:tokens(Vmap," \t"), VirtSegs = string:tokens(Virt,"/"), case lists:prefix(VirtSegs,ReqSegs) of true -> {LongestSoFar,_} = VdirSpec, if length(Virt) > length(LongestSoFar) -> %% reassemble (because physical %% path may have spaces) Phys = yaws:join_sep(PhysParts, " "), {ReqSegs, {Virt, Phys}}; true -> Acc end; false -> Acc end; _Else -> %% irrelevant member of opaque list. no change in %% accumulator Acc end end, {RequestSegs,{"",""}}, Opaquelist), case Matched of {_RequestSegs, {"",""}} -> %% no virtual dir corresponding to this http_request.path %% NOTE - we *don't* know that the state of ARG#arg.docroot %% currently reflects the main docroot %% specified for the virtual server in the conf file. %% This is because we may be being called from a page that is %% under a vdir, and so docroot may %% have been rewritten. It may also have been rewritten by an %% appmod or arg_rewrite_mod. %% Therefore we need to get it directly from the sconf record. Result = {"",SC#sconf.docroot}; {_RequestSegs, {Virt,DocRoot }} -> %%sanitize Virt & DocRoot so that they are correct with %% regards to leading & trailing slashes case string:right(Virt,1) of "/" -> VirtualDir = Virt; _ -> VirtualDir = Virt ++ "/" end, DR = string:strip(DocRoot,right,$/), Result = {VirtualDir, DR} end, %% return {VdirURI, Physpath} - i.e tuple representing the data %% specified in conf file for the 'vdir' directive. Result. close_accepted_if_max(GS,{ok, _Socket}) when (GS#gs.gconf)#gconf.max_connections == nolimit -> ok; close_accepted_if_max(GS,{ok, Socket}) -> MaxCon = (GS#gs.gconf)#gconf.max_connections, NumCon = GS#gs.connections, if NumCon < MaxCon -> ok; true -> S=case peername(Socket, GS#gs.ssl) of {unknown, unknown} -> "unknown"; {IP, Port} -> io_lib:format("~s:~w", [inet_parse:ntoa(IP), Port]) end, error_logger:format( "Max connections reached - closing conn to ~s~n",[S]), if GS#gs.ssl == nossl -> gen_tcp:close(Socket); GS#gs.ssl == ssl -> ssl:close(Socket) end end; close_accepted_if_max(_,_) -> ok. code_change(_OldVsn, Data, _Extra) -> {ok, Data}. fwdproxy_url(ARG) -> Headers = ARG#arg.headers, {abs_path, Path} = (ARG#arg.req)#http_request.path, {Host0, Port0} = yaws:split_at(Headers#headers.host, $:), {Host, Port} = case string:to_integer(Port0) of {Port1, []} -> {Host0, Port1}; _ -> {Headers#headers.host, undefined} end, #url{scheme = http, host = Host, port = Port, path = Path}. maybe_set_page_options() -> case erase(page_options) of undefined -> ok; Options -> deepforeach( fun(X) -> case X of {header, Header} -> yaws:accumulate_header(Header); {status, Code} -> yaws:outh_set_status_code(Code); _Other -> ?Debug("Got ~p in page option list.", [_Other]) end end, Options) end. yaws-2.0.2/src/jsonrpc.erl0000664000175000017500000001027212605311412012367 00000000000000%% Copyright (C) 2006 Gaspar Chilingarov %% Gurgen Tumanyan %% All rights reserved. %% %% %% Redistribution and use in source and binary forms, with or without %% modification, are permitted provided that the following conditions %% are met: %% %% 1. Redistributions of source code must retain the above copyright %% notice, this list of conditions and the following disclaimer. %% 2. Redistributions in binary form must reproduce the above %% copyright notice, this list of conditions and the following %% disclaimer in the documentation and/or other materials provided %% with the distribution. %% %% THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS %% OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED %% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE %% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY %% DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL %% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE %% GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS %% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, %% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING %% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS %% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -module(jsonrpc). -author("Gaspar Chilingarov , Gurgen Tumanyan "). -export([call/3]). -export([s/2]). % extract element from proplist %%% %%% call function calls json-rpc method on remote host %%% %%% URL - remote server url (may use https) %%% Options - option list to be passed to http:request %%% (ssl options ot timeout, for example) %%% Payload -> {call, MethodName, Args} tuple %%% MethodName -> atom %%% Args -> list %%% call(URL, Options, Payload) -> try {ok, CallPayloadDeep} = encode_call_payload(Payload), CallPayload = lists:flatten(CallPayloadDeep), {ok, Response} = httpc:request( post, {URL,[{"Content-Length",length(CallPayload)}], "application/x-www-form-urlencoded",CallPayload}, Options, []), RespBody = if (size(Response) == 2) or (size(Response) == 3) -> element(size(Response), Response) end, decode_call_payload(RespBody) catch error:Err-> error_logger:error_report([{'json_rpc:call', error}, {error, Err}, {stack, erlang:get_stacktrace()}]), {error,Err} end. %%% %%% json-rpc.org defines such structure for making call %%% encode_call_payload({call, Method, Args}) when is_list(Args) -> %% id makes sense when there are many requests in same %% communication channel and replies can come in random %% order here it can be changed to something less expensive ID = element(3, yaws:unique_triple()), Struct = json2:encode({struct, [{"jsonrpc", "2.0"}, {method, Method}, {params, {array, Args}}, {id, ID}]}), {ok, Struct}. %%% %%% decode response structure %%% decode_call_payload(JSonStr) -> {ok, JSON} = json2:decode_string(JSonStr), Result = s(JSON, result), Error = s(JSON, error), case Error of undefined -> {ok,{response,[Result]}}; % make it compliant with xmlrpc response Error -> {error, Error} end. %%% lookup element in proplist s({struct, List}, ElemName) -> s(List, ElemName); s(List, ElemName) when is_list(List) -> case lists:keysearch(ElemName,1,List) of {value,{ElemName,Val}} -> Val; false when is_atom(ElemName) -> ElemList = atom_to_list(ElemName), case lists:keysearch(ElemList,1,List) of {value,{ElemList,Val}} -> Val; _ -> undefined end; _ -> undefined end. % vim: tabstop=4 ft=erlang yaws-2.0.2/src/yaws_revproxy.erl0000664000175000017500000007305512605311412013662 00000000000000%%%------------------------------------------------------------------- %%% File : yaws_revproxy.erl %%% Author : %%% Description : reverse proxy %%% %%% Created : 3 Dec 2003 by %%%------------------------------------------------------------------- -module(yaws_revproxy). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). -export([out/1]). %% reverse proxy implementation. %% the revproxy internal state -record(revproxy, {srvsock, %% the socket opened on the backend server type, %% the socket type: ssl | nossl cliconn_status, %% "Connection:" header value: srvconn_status, %% "keep-alive' or "close" state, %% revproxy state: %% sendheaders | sendcontent | sendchunk | %% recvheaders | recvcontent | recvchunk | %% terminate prefix, %% The prefix to strip and add url, %% the url we're proxying to r_meth, %% what req method are we processing r_host, %% and value of Host: for the cli request resp, %% response received from the server headers, %% and associated headers srvdata, %% the server data is_chunked, %% true if the response is chunked intercept_mod %% revproxy request/response intercept module }). %% TODO: Activate proxy keep-alive with a new option ? -define(proxy_keepalive, false). %% Initialize the connection to the backend server. If an error occurred, return %% an error 404. out(#arg{req=Req, headers=Hdrs, state=#proxy_cfg{url=URL}=State}=Arg) -> case connect(URL) of {ok, Sock, Type} -> ?Debug("Connection established on ~p: Socket=~p, Type=~p~n", [URL, Sock, Type]), RPState = #revproxy{srvsock = Sock, type = Type, state = sendheaders, prefix = State#proxy_cfg.prefix, url = URL, r_meth = Req#http_request.method, r_host = Hdrs#headers.host, intercept_mod = State#proxy_cfg.intercept_mod}, out(Arg#arg{state=RPState}); _ERR -> ?Debug("Connection failed: ~p~n", [_ERR]), out404(Arg) end; %% Send the client request to the server then check if the request content is %% chunked or not out(#arg{state=#revproxy{}=RPState}=Arg) when RPState#revproxy.state == sendheaders -> ?Debug("Send request headers to backend server: ~n" " - ~s~n", [?format_record(Arg#arg.req, http_request)]), Req = rewrite_request(RPState, Arg#arg.req), Hdrs0 = Arg#arg.headers, Hdrs = rewrite_client_headers(RPState, Hdrs0), {NewReq, NewHdrs} = case RPState#revproxy.intercept_mod of undefined -> {Req, Hdrs}; InterceptMod -> case catch InterceptMod:rewrite_request( Req, Hdrs) of {ok, NewReq0, NewHdrs0} -> {NewReq0, NewHdrs0}; InterceptError -> error_logger:error_msg( "revproxy intercept module ~p:" "rewrite_request failed: ~p~n", [InterceptMod, InterceptError]), exit({error, intercept_mod}) end end, ReqStr = yaws_api:reformat_request(NewReq), HdrsStr = yaws:headers_to_str(NewHdrs), case send(RPState, [ReqStr, "\r\n", HdrsStr, "\r\n"]) of ok -> TE = yaws:to_lower(Hdrs#headers.transfer_encoding), RPState1 = if (Hdrs#headers.content_length == undefined andalso TE == "chunked") -> ?Debug("Request content is chunked~n", []), RPState#revproxy{state=sendchunk}; true -> RPState#revproxy{state=sendcontent} end, out(Arg#arg{state=RPState1}); {error, Reason} -> ?Debug("TCP error: ~p~n", [Reason]), case Reason of closed -> ok; _ -> close(RPState) end, outXXX(500, Arg) end; %% Send the request content to the server. Here the content is not chunked. But %% it can be split because of 'partial_post_size' value. out(#arg{state=RPState}=Arg) when RPState#revproxy.state == sendcontent -> case Arg#arg.clidata of {partial, Bin} -> ?Debug("Send partial content to backend server: ~p bytes~n", [size(Bin)]), case send(RPState, Bin) of ok -> {get_more, undefined, RPState}; {error, Reason} -> ?Debug("TCP error: ~p~n", [Reason]), case Reason of closed -> ok; _ -> close(RPState) end, outXXX(500, Arg) end; Bin when is_binary(Bin), Bin /= <<>> -> ?Debug("Send content to backend server: ~p bytes~n", [size(Bin)]), case send(RPState, Bin) of ok -> RPState1 = RPState#revproxy{state=recvheaders}, out(Arg#arg{state=RPState1}); {error, Reason} -> ?Debug("TCP error: ~p~n", [Reason]), case Reason of closed -> ok; _ -> close(RPState) end, outXXX(500, Arg) end; _ -> ?Debug("no content found~n", []), RPState1 = RPState#revproxy{state=recvheaders}, out(Arg#arg{state=RPState1}) end; %% Send the request content to the server. Here the content is chunked, so we %% must rebuild the chunk before sending it. Chunks can have different size than %% the original request because of 'partial_post_size' value. out(#arg{state=RPState}=Arg) when RPState#revproxy.state == sendchunk -> case Arg#arg.clidata of {partial, Bin} -> ?Debug("Send chunked content to backend server: ~p bytes~n", [size(Bin)]), Res = send(RPState, [yaws:integer_to_hex(size(Bin)),"\r\n",Bin,"\r\n"]), case Res of ok -> {get_more, undefined, RPState}; {error, Reason} -> ?Debug("TCP error: ~p~n", [Reason]), case Reason of closed -> ok; _ -> close(RPState) end, outXXX(500, Arg) end; <<>> -> ?Debug("Send last chunk to backend server~n", []), case send(RPState, "0\r\n\r\n") of ok -> RPState1 = RPState#revproxy{state=recvheaders}, out(Arg#arg{state=RPState1}); {error, Reason} -> ?Debug("TCP error: ~p~n", [Reason]), case Reason of closed -> ok; _ -> close(RPState) end, outXXX(500, Arg) end end; %% The request and its content were sent. Now, we try to read the response %% headers. Then we check if the response content is chunked or not. out(#arg{state=RPState}=Arg) when RPState#revproxy.state == recvheaders -> Res = yaws:http_get_headers(RPState#revproxy.srvsock, RPState#revproxy.type), case Res of {error, {too_many_headers, _Resp}} -> ?Debug("Response headers too large from backend server~n", []), close(RPState), outXXX(500, Arg); {Resp0, RespHdrs0} when is_record(Resp0, http_response) -> ?Debug("Response headers received from backend server:~n" " - ~s~n - ~s~n", [?format_record(Resp0, http_response), ?format_record(RespHdrs0, headers)]), {Resp, RespHdrs} = case RPState#revproxy.intercept_mod of undefined -> {Resp0, RespHdrs0}; InterceptMod -> case catch InterceptMod:rewrite_response( Resp0, RespHdrs0) of {ok, NewResp, NewRespHdrs} -> {NewResp, NewRespHdrs}; InterceptError -> error_logger:error_msg( "revproxy intercept module ~p:" "rewrite_response failure: ~p~n", [InterceptMod, InterceptError]), exit({error, intercept_mod}) end end, {CliConn, SrvConn} = get_connection_status( (Arg#arg.req)#http_request.version, Arg#arg.headers, RespHdrs ), RPState1 = RPState#revproxy{cliconn_status = CliConn, srvconn_status = SrvConn, resp = Resp, headers = RespHdrs}, if RPState1#revproxy.r_meth =:= 'HEAD' -> RPState2 = RPState1#revproxy{state=terminate}, out(Arg#arg{state=RPState2}); Resp#http_response.status =:= 100 orelse Resp#http_response.status =:= 204 orelse Resp#http_response.status =:= 205 orelse Resp#http_response.status =:= 304 orelse Resp#http_response.status =:= 406 -> RPState2 = RPState1#revproxy{state=terminate}, out(Arg#arg{state=RPState2}); true -> RPState2 = case RespHdrs#headers.content_length of undefined -> TE = yaws:to_lower( RespHdrs#headers.transfer_encoding), case TE of "chunked" -> ?Debug("Response content is chunked~n", []), RPState1#revproxy{state=recvchunk}; _ -> RPState1#revproxy{ cliconn_status="close", srvconn_status="close", state=recvcontent} end; _ -> RPState1#revproxy{state=recvcontent} end, out(Arg#arg{state=RPState2}) end; {_R, _H} -> %% bad_request ?Debug("Bad response received from backend server: ~p~n", [_R]), close(RPState), outXXX(500, Arg); closed -> ?Debug("TCP error: ~p~n", [closed]), outXXX(500, Arg) end; %% The response content is not chunked. out(#arg{state=RPState}=Arg) when RPState#revproxy.state == recvcontent -> Len = case (RPState#revproxy.headers)#headers.content_length of undefined -> undefined; CLen -> list_to_integer(CLen) end, SC=get(sc), if is_integer(Len) andalso Len =< SC#sconf.partial_post_size -> case read(RPState, Len) of {ok, Data} -> ?Debug("Response content received from the backend server: " "~p bytes~n", [size(Data)]), RPState1 = RPState#revproxy{state = terminate, is_chunked = false, srvdata = {content, Data}}, out(Arg#arg{state=RPState1}); {error, Reason} -> ?Debug("TCP error: ~p~n", [Reason]), case Reason of closed -> ok; _ -> close(RPState) end, outXXX(500, Arg) end; is_integer(Len) -> %% Here partial_post_size is always an integer BlockSize = SC#sconf.partial_post_size, BlockCount = Len div BlockSize, LastBlock = Len rem BlockSize, SrvData = {block, BlockCount, BlockSize, LastBlock}, RPState1 = RPState#revproxy{state = terminate, is_chunked = true, srvdata = SrvData}, out(Arg#arg{state=RPState1}); true -> SrvData = {block, undefined, undefined, undefined}, RPState1 = RPState#revproxy{state = terminate, is_chunked = true, srvdata = SrvData}, out(Arg#arg{state=RPState1}) end; %% The response content is chunked. Read the first chunk here and spawn a %% process to read others. out(#arg{state=RPState}=Arg) when RPState#revproxy.state == recvchunk -> case read_chunk(RPState) of {ok, Data} -> ?Debug("First chunk received from the backend server : " "~p bytes~n", [size(Data)]), RPState1 = RPState#revproxy{state = terminate, is_chunked = (Data /= <<>>), srvdata = {stream, Data}}, out(Arg#arg{state=RPState1}); {error, Reason} -> ?Debug("TCP error: ~p~n", [Reason]), case Reason of closed -> ok; _ -> close(RPState) end, outXXX(500, Arg) end; %% Now, we return the result and we let yaws_server deals with it. If it is %% possible, we try to cache the connection. out(#arg{state=RPState}=Arg) when RPState#revproxy.state == terminate -> case RPState#revproxy.srvconn_status of "close" when RPState#revproxy.is_chunked == false -> close(RPState); "close" -> ok; _ -> cache_connection(RPState) end, AllHdrs = [{header, H} || H <- yaws_api:reformat_header( rewrite_server_headers(RPState) )], ?Debug("~p~n", [AllHdrs]), Res = [ {status, (RPState#revproxy.resp)#http_response.status}, {allheaders, AllHdrs} ], case RPState#revproxy.srvdata of {content, <<>>} -> Res; {content, Data} -> MimeType = (RPState#revproxy.headers)#headers.content_type, Res ++ [{content, MimeType, Data}]; {stream, <<>>} -> %% Chunked response with only the last empty chunk: do not spawn a %% process to manage chunks yaws_api:stream_chunk_end(self()), MimeType = (RPState#revproxy.headers)#headers.content_type, Res ++ [{streamcontent, MimeType, <<>>}]; {stream, Chunk} -> Self = self(), GC = get(gc), spawn(fun() -> put(gc, GC), recv_next_chunk(Self, Arg) end), MimeType = (RPState#revproxy.headers)#headers.content_type, Res ++ [{streamcontent, MimeType, Chunk}]; {block, BlockCnt, BlockSz, LastBlock} -> GC = get(gc), Pid = spawn(fun() -> put(gc, GC), receive {ok, YawsPid} -> recv_blocks(YawsPid, Arg, BlockCnt, BlockSz, LastBlock); {discard, YawsPid} -> recv_blocks(YawsPid, Arg, 0, BlockSz, 0) end end), MimeType = (RPState#revproxy.headers)#headers.content_type, Res ++ [{streamcontent_from_pid, MimeType, Pid}]; _ -> Res end; %% Catch unexpected state by sending an error 500 out(#arg{state=RPState}=Arg) -> ?Debug("Unexpected revproxy state:~n - ~s~n", [?format_record(RPState, revproxy)]), case RPState#revproxy.srvsock of undefined -> ok; _ -> close(RPState) end, outXXX(500, Arg). %%========================================================================== out404(Arg) -> SC=get(sc), (SC#sconf.errormod_404):out404(Arg,get(gc),SC). outXXX(Code, _Arg) -> Content = ["

", integer_to_list(Code), $\ , yaws_api:code_to_phrase(Code), "

"], [ {status, Code}, {header, {connection, "close"}}, {content, "text/html", Content} ]. %%========================================================================== %% This function is used to read a chunk and to stream it to the client. recv_next_chunk(YawsPid, #arg{state=RPState}=Arg) -> case read_chunk(RPState) of {ok, <<>>} -> ?Debug("Last chunk received from the backend server~n", []), yaws_api:stream_chunk_end(YawsPid), case RPState#revproxy.srvconn_status of "close" -> close(RPState); _ -> ok %% Cached by the main process end; {ok, Data} -> ?Debug("Next chunk received from the backend server : " "~p bytes~n", [size(Data)]), yaws_api:stream_chunk_deliver(YawsPid, Data), recv_next_chunk(YawsPid, Arg); {error, Reason} -> ?Debug("TCP error: ~p~n", [Reason]), yaws_api:stream_chunk_end(YawsPid), case Reason of closed -> ok; _ -> close(RPState) end end. %%========================================================================== %% This function reads blocks from the server and streams them to the client. recv_blocks(YawsPid, #arg{state=RPState}=Arg, undefined, undefined, undefined) -> case read(RPState) of {ok, <<>>} -> %% no data, wait 100 msec to avoid time-consuming loop and retry timer:sleep(100), recv_blocks(YawsPid, Arg, undefined, undefined, undefined); {ok, Data} -> ?Debug("Response content received from the backend server : " "~p bytes~n", [size(Data)]), ok = yaws_api:stream_process_deliver(Arg#arg.clisock, Data), recv_blocks(YawsPid, Arg, undefined, undefined, undefined); {error, closed} -> yaws_api:stream_process_end(closed, YawsPid); {error, _Reason} -> ?Debug("TCP error: ~p~n", [_Reason]), yaws_api:stream_process_end(closed, YawsPid), close(RPState) end; recv_blocks(YawsPid, #arg{state=RPState}=Arg, 0, _, 0) -> yaws_api:stream_process_end(Arg#arg.clisock, YawsPid), case RPState#revproxy.srvconn_status of "close" -> close(RPState); _ -> ok %% Cached by the main process end; recv_blocks(YawsPid, #arg{state=RPState}=Arg, 0, _, LastBlock) -> Sock = Arg#arg.clisock, case read(RPState, LastBlock) of {ok, Data} -> ?Debug("Response content received from the backend server : " "~p bytes~n", [size(Data)]), ok = yaws_api:stream_process_deliver(Sock, Data), yaws_api:stream_process_end(Sock, YawsPid), case RPState#revproxy.srvconn_status of "close" -> close(RPState); _ -> ok %% Cached by the main process end; {error, Reason} -> ?Debug("TCP error: ~p~n", [Reason]), yaws_api:stream_process_end(closed, YawsPid), case Reason of closed -> ok; _ -> close(RPState) end end; recv_blocks(YawsPid, #arg{state=RPState}=Arg, BlockCnt, BlockSz, LastBlock) -> case read(RPState, BlockSz) of {ok, Data} -> ?Debug("Response content received from the backend server : " "~p bytes~n", [size(Data)]), ok = yaws_api:stream_process_deliver(Arg#arg.clisock, Data), recv_blocks(YawsPid, Arg, BlockCnt-1, BlockSz, LastBlock); {error, Reason} -> ?Debug("TCP error: ~p~n", [Reason]), yaws_api:stream_process_end(closed, YawsPid), case Reason of closed -> ok; _ -> close(RPState) end end. %%========================================================================== %% TODO: find a better way to cache connections to backend servers. Here we can %% have 1 connection per gserv process for each backend server. get_cached_connection(URL) -> Key = lists:flatten(yaws_api:reformat_url(URL)), case erase(Key) of undefined -> undefined; {Sock, nossl} -> case gen_tcp:recv(Sock, 0, 1) of {error, closed} -> ?Debug("Invalid cached connection~n", []), undefined; _ -> ?Debug("Found cached connection to ~s~n", [Key]), {ok, Sock, nossl} end; {Sock, ssl} -> case ssl:recv(Sock, 0, 1) of {error, closed} -> ?Debug("Invalid cached connection~n", []), undefined; _ -> ?Debug("Found cached connection to ~s~n", [Key]), {ok, Sock, ssl} end end. cache_connection(RPState) -> Key = lists:flatten(yaws_api:reformat_url(RPState#revproxy.url)), ?Debug("Cache connection to ~s~n", [Key]), InitDB0 = get(init_db), InitDB1 = lists:keystore( Key, 1, InitDB0, {Key, {RPState#revproxy.srvsock, RPState#revproxy.type}} ), put(init_db, InitDB1), ok. %%========================================================================== connect(URL) -> case get_cached_connection(URL) of {ok, Sock, Type} -> {ok, Sock, Type}; undefined -> do_connect(URL) end. do_connect(URL) -> Opts = [ binary, {packet, raw}, {active, false}, {reuseaddr, true} ], case URL#url.scheme of http -> Port = case URL#url.port of undefined -> 80; P -> P end, case yaws:tcp_connect(URL#url.host, Port, Opts) of {ok, S} -> {ok, S, nossl}; Err -> Err end; https -> Port = case URL#url.port of undefined -> 443; P -> P end, case yaws:ssl_connect(URL#url.host, Port, Opts) of {ok, S} -> {ok, S, ssl}; Err -> Err end; _ -> {error, unsupported_protocol} end. send(#revproxy{srvsock=Sock, type=ssl}, Data) -> ssl:send(Sock, Data); send(#revproxy{srvsock=Sock, type=nossl}, Data) -> gen_tcp:send(Sock, Data). read(#revproxy{srvsock=Sock, type=Type}) -> yaws:setopts(Sock, [{packet, raw}, binary], Type), yaws:do_recv(Sock, 0, Type). read(RPState, Len) -> yaws:setopts(RPState#revproxy.srvsock, [{packet, raw}, binary], RPState#revproxy.type), read(RPState, Len, []). read(_, 0, Data) -> {ok, iolist_to_binary(lists:reverse(Data))}; read(RPState = #revproxy{srvsock=Sock, type=Type}, Len, Data) -> case yaws:do_recv(Sock, Len, Type) of {ok, Bin} -> read(RPState, Len-size(Bin), [Bin|Data]); {error, Reason} -> {error, Reason} end. read_chunk(#revproxy{srvsock=Sock, type=Type}) -> try yaws:setopts(Sock, [binary, {packet, line}], Type), %% Ignore chunk extentions {Len, _Exts} = yaws:get_chunk_header(Sock, Type), yaws:setopts(Sock, [binary, {packet, raw}], Type), if Len == 0 -> %% Ignore chunk trailer yaws:get_chunk_trailer(Sock, Type), {ok, <<>>}; true -> B = yaws:get_chunk(Sock, Len, 0, Type), ok = yaws:eat_crnl(Sock, Type), {ok, iolist_to_binary(B)} end catch _:Reason -> {error, Reason} end. close(#revproxy{srvsock=Sock, type=ssl}) -> ssl:close(Sock); close(#revproxy{srvsock=Sock, type=nossl}) -> gen_tcp:close(Sock). get_connection_status(Version, ReqHdrs, RespHdrs) -> CliConn = case Version of {0,9} -> "close"; {1, 0} -> case ReqHdrs#headers.connection of undefined -> "close"; C1 -> yaws:to_lower(C1) end; {1, 1} -> case ReqHdrs#headers.connection of undefined -> "keep-alive"; C1 -> yaws:to_lower(C1) end end, ?Debug("Client Connection header: ~p~n", [CliConn]), %% below, ignore dialyzer warning: %% "The pattern 'true' can never match the type 'false'" SrvConn = case ?proxy_keepalive of true -> case RespHdrs#headers.connection of undefined -> CliConn; C2 -> yaws:to_lower(C2) end; false -> "close" end, ?Debug("Server Connection header: ~p~n", [SrvConn]), {CliConn, SrvConn}. %%========================================================================== rewrite_request(RPState, Req) -> ?Debug("Request path to rewrite: ~p~n", [Req#http_request.path]), {abs_path, Path} = Req#http_request.path, NewPath = strip_prefix(Path, RPState#revproxy.prefix), ?Debug("New Request path: ~p~n", [NewPath]), Req#http_request{path = {abs_path, NewPath}}. rewrite_client_headers(RPState, Hdrs) -> ?Debug("Host header to rewrite: ~p~n", [Hdrs#headers.host]), Host = case Hdrs#headers.host of undefined -> undefined; _ -> ProxyUrl = RPState#revproxy.url, [ProxyUrl#url.host, case ProxyUrl#url.port of undefined -> []; P -> [$:|integer_to_list(P)] end] end, ?Debug("New Host header: ~p~n", [Host]), Hdrs#headers{host = Host}. rewrite_server_headers(RPState) -> Hdrs = RPState#revproxy.headers, ?Debug("Location header to rewrite: ~p~n", [Hdrs#headers.location]), Loc = case Hdrs#headers.location of undefined -> undefined; L -> ?Debug("parse_url(~p)~n", [L]), LocUrl = (catch yaws_api:parse_url(L)), ProxyUrl = RPState#revproxy.url, if LocUrl#url.scheme == ProxyUrl#url.scheme andalso LocUrl#url.host == ProxyUrl#url.host andalso LocUrl#url.port == ProxyUrl#url.port -> rewrite_loc_url(RPState, LocUrl); element(1, L) == 'EXIT' -> rewrite_loc_rel(RPState, L); true -> L end end, ?Debug("New Location header: ~p~n", [Loc]), %% FIXME: And we also should do cookies here ... Hdrs#headers{location = Loc, connection = RPState#revproxy.cliconn_status}. %% Rewrite a properly formatted location redir rewrite_loc_url(RPState, LocUrl) -> SC=get(sc), Scheme = yaws:redirect_scheme(SC), RedirHost = yaws:redirect_host(SC, RPState#revproxy.r_host), [Scheme, RedirHost, slash_append(RPState#revproxy.prefix, LocUrl#url.path)]. %% This is the case for broken webservers that reply with %% Location: /path %% or even worse, Location: path rewrite_loc_rel(RPState, Loc) -> SC=get(sc), Scheme = yaws:redirect_scheme(SC), RedirHost = yaws:redirect_host(SC, RPState#revproxy.r_host), [Scheme, RedirHost, Loc]. strip_prefix("", "") -> "/"; strip_prefix(P, "") -> P; strip_prefix(P, "/") -> P; strip_prefix([H|T1], [H|T2]) -> strip_prefix(T1, T2). slash_append("/", [$/|T]) -> [$/|T]; slash_append("/", T) -> [$/|T]; slash_append([], [$/|T]) -> [$/|T]; slash_append([], T) -> [$/|T]; slash_append([H|T], X) -> [H | slash_append(T, X)]. yaws-2.0.2/src/yaws_runmod_lock.erl0000664000175000017500000003242012605311412014267 00000000000000%%---------------------------------------------------------------------- %%% File : yaws_runmod_lock.erl %%% Created : 11 Nov 2012 by tjeerd %%% Purpose : Generic locking server %%% - lock a resource identified by its path %%% - this path uses a forward slash ("/") as separator %%% - use unique path for the resource (i.e. filesystem path) %%% - unique: server wide, locking functionality can be shared %%% - always use an absolute path starting with a slash %%% - lock scope can be exclusive (default) or shared %%% - depth can be 0 or infinity (default) %%%--------------------------------------------------------------------- -module(yaws_runmod_lock). -define(DEBUG(X), io:format(X)). -define(DEBUG(X,Y), io:format(X,Y)). -include("../include/yaws_lock.hrl"). -include("../include/yaws_api.hrl"). -include("../include/yaws.hrl"). -include("yaws_debug.hrl"). -include_lib("kernel/include/file.hrl"). -behaviour(gen_server). %% start/stop manually -export([start/0,stop/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% API - main use %% %% lock(Path,Lock) -> {ok,Id}|{error,Reason} %% unlock(Path,Id) -> ok|{error,Reason} %% locked(Path) -> true|false %% check(Path,Id) -> ok|{error,Reason} %% discover(Path) -> [Lock] %% started() -> true|false %% -export([lock/2, unlock/2, locked/1, check/2, discover/1, clear/0, started/0]). %% API - console debugging %% %% report() -> Report %% dump() -> Dump %% clear_manual() -> ok %% -export([report/0, dump/0, cleanup_manual/0]). start() -> gen_server:start_link({local,?MODULE},?MODULE,[],[]). stop() -> gen_server:call(?MODULE,stop). lock(Path,Lock) -> gen_server:call(?MODULE,{lock,Path,Lock}). unlock(Path,Id) -> gen_server:call(?MODULE,{unlock,Path,Id}). locked(Path) -> gen_server:call(?MODULE,{locked,Path}). check(Path,Id) -> gen_server:call(?MODULE,{check,Path,Id}). discover(Path) -> gen_server:call(?MODULE,{discover,Path}). report() -> gen_server:call(?MODULE,report). dump() -> gen_server:call(?MODULE,dump). clear() -> gen_server:call(?MODULE,clear). cleanup_manual() -> erlang:send(?MODULE,cleanup). started() -> case erlang:whereis(?MODULE) of undefined -> false; _ -> true end. %% init/1 init([]) -> % Table is a tree consisting of {Name, Locks, Children} tuples error_logger:info_msg("Initializing resource locking server ...~n"), Table = [], erlang:send_after(?CLEANUP_INTERVAL*1000, self(), cleanup), {ok, Table}. %% handle_call/3 handle_call({lock,Path,Lock}, _From, Table) -> try T0 = yaws:get_time_tuple(), Id = case Lock#lock.id of undefined -> locktoken(); _ -> Lock#lock.id end, %?DEBUG("create lock ~p for ~p~n",[Id,Path]), Lock1 = Lock#lock{path=Path,id=Id,timestamp=T0}, Path1 = filename:split(["/",Path]), Table1 = do_lock(Path1,Lock1,Table), {reply, {ok,Id}, Table1} catch Status -> {reply, {error, Status}, Table}; _Error:Reason -> error_logger:error_msg("Unexpected error: ~p~n~p~n", [Reason,erlang:get_stacktrace()]), {reply, {error, Reason}, Table} end; handle_call({unlock,Path,Id}, _From, Table) -> % even if the lock is not found, its removal is succesfull Path1 = filename:split(["/",Path]), {Status,Table1} = do_unlock(Path1,Id,Table), {reply, Status, Table1}; handle_call({locked,Path}, _From, Table) -> L = filename:split(["/",Path]), Lock = do_locked(L,Table), {reply, Lock, Table}; handle_call({check,Path,Id}, _From, Table) -> L = filename:split(["/",Path]), Lock = do_check(L,Id,Table), {reply, Lock, Table}; handle_call({discover,Path}, _From, Table) -> L = filename:split(["/",Path]), Lock = do_discover(L,Table), {reply, Lock, Table}; handle_call(report, _From, Table) -> do_report(Table), {reply, ok, Table}; handle_call(dump, _From, Table) -> {reply, Table, Table}; handle_call(stop, _From, Table) -> {stop, normal, stopped, Table}; handle_call(clear, _From, _Table) -> {reply, ok, []}. %% handle_cast/2 handle_cast(_Msg, State) -> {noreply, State}. %% handle_info/2 handle_info(cleanup, Table) -> erlang:send_after(?CLEANUP_INTERVAL*1000, self(), cleanup), Table1 = do_cleanup(Table), {noreply, Table1}. %% terminate/2 terminate(_Reason, _State) -> ok. %% code_change/3 code_change(_OldVsn, State, _Extra) -> {ok, State}. %%---------------------------------------------------------------------- %% do_lock(Lock,Path,Table) -> Table %% do_lock([H],Lock,Table) -> case lists:keysearch(H,1,Table) of {value,{H,Locks,Children}} -> case do_lock_check(Locks,Lock#lock.id) of this -> % refresh lock only when same resource Locks1 = do_lock_refresh(Locks,Lock), lists:keyreplace(H,1,Table,{H,Locks1,Children}); {shared,_} when Lock#lock.scope == shared -> lists:keyreplace(H,1,Table,{H,[Lock|Locks],Children}); unlocked -> lists:keyreplace(H,1,Table,{H,[Lock],Children}); _ -> throw(locked) end; false -> lists:keystore(H,1,Table,{H,[Lock],[]}) end; do_lock([H|T],Lock,Table) -> case lists:keysearch(H,1,Table) of {value,{H,Locks,Children}} -> %%%% hier gebleven case do_lock_check(Locks,Lock#lock.id) of {_,infinity} when Lock#lock.scope == exclusive -> throw(locked); _ -> lists:keyreplace(H,1,Table,{H,Locks, do_lock(T,Lock,Children)}) end; false -> lists:keystore(H,1,Table,{H,[],do_lock(T,Lock,[])}) end. %% do_lock_check/2 returns %% - unlocked when no lock found or %% - {scope,depth} when locked %% - this when Id matches do_lock_check(Locks,Id) -> do_lock_check(Locks,Id,unlocked). do_lock_check([],_Id,Result) -> Result; do_lock_check([H|_T],Id,_Result) when H#lock.id == Id -> this; do_lock_check([H|T],Id,_Result) -> case H#lock.depth of infinity -> {H#lock.scope,infinity}; 0 -> do_lock_check(T,Id,{H#lock.scope,0}) end. do_lock_refresh(Locks,Lock) -> do_lock_refresh(Locks,Lock,[]). do_lock_refresh([],_Lock,Result) -> Result; do_lock_refresh([H|T],Lock,Result) when H#lock.id == Lock#lock.id -> do_lock_refresh(T,Lock,[Lock|Result]); do_lock_refresh([H|T],Lock,Result) -> do_lock_refresh(T,Lock,[H|Result]). %%---------------------------------------------------------------------- %% do_unlock(Path,Id,Table) -> Table %% do_unlock([H],Id,Table) -> case lists:keysearch(H,1,Table) of {value,{H,Locks,Children}} -> {Status,Locks1} = do_unlock_id(Locks,Id), case {Locks1,Children} of {[],[]} -> {_,_,Return} = lists:keytake(H,1,Table), {Status,Return}; _ -> Result = lists:keyreplace(H,1,Table,{H,Locks1,Children}), {Status,Result} end; false -> {not_found,Table} end; do_unlock([H|T],Id,Table) -> case lists:keysearch(H,1,Table) of {value,{H,Locks,Children}} -> {Status,Children1} = do_unlock(T,Id,Children), case {Locks,Children1} of {[],[]} -> {_,_,Return} = lists:keytake(H,1,Table), {Status,Return}; _ -> Result = lists:keyreplace(H,1,Table,{H,Locks,Children1}), {Status,Result} end; false -> {not_found,Table} end. do_unlock_id([],_Id) -> {not_found,[]}; do_unlock_id([H|T],Id) -> case H#lock.id of Id -> {ok,T}; _ -> {Status,Result} = do_unlock_id(T,Id), {Status,[H|Result]} end. %%---------------------------------------------------------------------- %% do_locked(Path,Table) -> Table %% do_locked([H],Table) -> case lists:keysearch(H,1,Table) of {value,{H,Locks,_}} when length(Locks)>0 -> true; _ -> false end; do_locked([H|T],Table) -> case lists:keysearch(H,1,Table) of {value,{H,_Locks,Children}} -> do_locked(T,Children); _ -> false end. %%---------------------------------------------------------------------- %% do_check(Path,Id,Table) -> Table %% do_check([H|T],Id,Table) -> case lists:keysearch(H,1,Table) of {value,{H,Locks,_}} when length(T)==0 -> do_check_locks(Locks,Id); {value,{H,_Lock,Children}} -> do_check(T,Id,Children); false -> {error,not_found} end. do_check_locks([],_Id) -> {error,not_found}; do_check_locks([H|T],Id) -> case H#lock.id of Id -> ok; _ -> do_check_locks(T,Id) end. %%---------------------------------------------------------------------- %% do_discover(Path,Table) -> Locks %% do_discover([H|T],Table) -> case lists:keysearch(H,1,Table) of {value,{H,Locks,_}} when length(T)==0 -> Locks; {value,{H,Locks,Children}} -> do_discover_depth_infinity(Locks)++do_discover(T,Children); false -> [] end. do_discover_depth_infinity([]) -> []; do_discover_depth_infinity([H|T]) -> Take = case H#lock.depth of infinity -> [H]; _ -> [] end, Take ++ do_discover_depth_infinity(T). %%---------------------------------------------------------------------- %% do_report(Path) -> Report %% do_report(Table) -> case Table of [] -> io:format("No locks.~n",[]); _ -> do_report([],Table) end. do_report(_Path,[]) -> ok; do_report(Path,[{Name,Locks,Children}|T]) -> Resource = filename:join(Path,Name), if length(Locks)>0 -> io:format("~p~n",[Resource]), do_report_locks(Locks); true -> [] end, do_report(Resource,Children), do_report(Path,T). do_report_locks([]) -> ok; do_report_locks([H|T]) -> io:format("... ~p lock with token ~p, scope ~p, depth ~p~n", [H#lock.type,H#lock.id,H#lock.scope,H#lock.depth]), do_report_locks(T). %%---------------------------------------------------------------------- %% do_cleanup(Table) -> Table %% do_cleanup([]) -> []; do_cleanup([{Name,Locks,Children}|T]) -> Locks1 = do_cleanup_locks(Locks), Children1 = do_cleanup(Children), if (length(Locks1)==0) and (length(Children1)==0) -> do_cleanup(T); true -> [{Name,Locks1,Children1}|do_cleanup(T)] end. do_cleanup_locks([]) -> []; do_cleanup_locks([H|T]) -> T0 = H#lock.timestamp, T1 = yaws:get_time_tuple(), Delta = timer:now_diff(T1,T0), if Delta > (H#lock.timeout*1000000) -> error_logger:info_msg("discarded lock ~p~n",[H#lock.id]), do_cleanup_locks(T); true -> [H|do_cleanup_locks(T)] end. %%---------------------------------------------------------------------- locktoken() -> % RFC4122 section 3 based UUID Version = 1, Variant = 2#10, Now = {_, _, Micro} = yaws:get_time_tuple(), Nowish = calendar:now_to_universal_time(Now), Timestamp = calendar:datetime_to_gregorian_seconds(Nowish) * 1000000000, <> = <>, Clocksequence = <>, <> = Clocksequence, Node = get_hwaddr(), UUID = <>, <> = UUID, lists:flatten(io_lib:format("~8.16.0b-~4.16.0b-~4.16.0b-~4.16.0b-~12.16.0b" ,[U0,U1,U2,U3,U4])). get_hwaddr() -> get_hwaddr(erlang:function_exported(inet, getifaddrs, 0)). get_hwaddr(true) -> {ok,Ifs} = inet:getifaddrs(), Addrs = [ lists:keysearch(hwaddr,1,Attr) || {_If,Attr} <- Ifs ], Addr = lists:max([ A || {value,{hwaddr,A}} <- Addrs ]), list_to_binary(Addr); get_hwaddr(false) -> %% this clause is for backward compatibility to R13 {ok, Ifs} = inet:getiflist(), Addrs = lists:foldl( fun([{hwaddr, HW}], Acc) -> [HW|Acc]; ([], Acc) -> Acc end, [], [begin {ok, HW} =inet:ifget(If, [hwaddr]), HW end || If <- Ifs]), HWAddrs = case Addrs of [] -> %% hwaddr doesn't work on Mac on R13. %% Fall back to ifconfig :( Ifconfig = os:cmd("/sbin/ifconfig -a"), {ok, Pat} = re:compile("ether\s+([0-9a-fA-F:]+)"), {match, Matches} = re:run(Ifconfig, Pat, [global, {capture, [1]}]), HWs = [string:substr(Ifconfig, At+1, Len) || [{At,Len}] <- Matches], [[erlang:list_to_integer(V, 16) || V <- string:tokens(S, ":")] || S <- HWs]; _ -> Addrs end, list_to_binary(lists:max(HWAddrs)). yaws-2.0.2/src/yaws.app.src0000664000175000017500000000156712605311412012467 00000000000000{application,yaws, [{description,"yaws WWW server"}, {vsn, {cmd, "sed -ne '1,/^YAWS_VSN=/s/^YAWS_VSN=//p' vsn.mk 2>/dev/null"}}, {modules,[]}, {registered, []}, {mod,{yaws_app,[]}}, {env, [ % {config, undefined}, % undefined | filename() % {debug, false}, % true | false % {trace, false}, % http | traffic | false % {traceoutput, false}, % true | false % {conf, "/etc/yaws.conf"}, % string() % {runmod, mymodule}, % atom() % {embedded, false}, % true | false % {id, "default"}, % string() % {pam_service, "system-auth"}, % string() % {pam_use_acct, true}, % true | false % {pam_use_sess, true} % true | false ]}, {applications,[kernel,stdlib@APPDEPS@]}]}. yaws-2.0.2/src/yaws_log.erl0000664000175000017500000003755712605311412012554 00000000000000%%---------------------------------------------------------------------- %%% File : yaws_log.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 26 Jan 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws_log). -author('klacke@hyber.org'). -include_lib("kernel/include/file.hrl"). -include_lib("kernel/include/inet.hrl"). -behaviour(gen_server). %% External exports -export([start_link/0, reopen_logs/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% API -export([accesslog/6, setup/2, authlog/4, rotate/1, add_sconf/1, del_sconf/1]). %% yaws_logger callbacks -export([ open_log/3, close_log/3, wrap_log/4, write_log/4 ]). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). %% 1 meg log we wrap -define(WRAP_LOG_SIZE, 1000000). -record(state, {running, dir, now, log_wrap_size = ?WRAP_LOG_SIZE, copy_errlog, resolve_hostnames = false}). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start_link() -> gen_server:start_link({local, yaws_log}, yaws_log, [], []). setup(GC, Sconfs) -> gen_server:call(?MODULE, {setup, GC, Sconfs}, infinity). add_sconf(SConf) -> gen_server:call(yaws_log, {soft_add_sc, SConf}, infinity). del_sconf(SConf) -> gen_server:call(yaws_log, {soft_del_sc, SConf}, infinity). accesslog(SConf, Ip, Req, InH, OutH, Time) -> catch yaws_logger:accesslog(SConf, Ip, Req, InH, OutH, Time). authlog(SConf, IP, Path, Item) -> catch yaws_logger:authlog(SConf, IP, Path, Item). rotate(Res) -> gen_server:cast(?MODULE, {yaws_hupped, Res}). %% Useful for embeddded yaws when we don't want yaws to %% automatically wrap the logs. reopen_logs() -> {ok, _GC, SCs} = yaws_api:getconf(), gen_server:call(?MODULE, {reopen, SCs}). %%%---------------------------------------------------------------------- %%% Callback functions from yaws_logger %%%---------------------------------------------------------------------- open_log(ServerName, Type, Dir) -> FileName = case os:type() of {win32,_ } -> lists:map(fun($:) -> $.; (C ) -> C end, ServerName); _ -> ServerName end, A = filename:join([Dir, FileName ++ "." ++ atom_to_list(Type)]), case file:open(A, [write, raw, append]) of {ok, Fd} -> {true, {Fd, A}}; _Err -> error_logger:format("Cannot open ~p",[A]), false end. close_log(_ServerName, _Type, {Fd, _FileName}) -> file:close(Fd). wrap_log(_ServerName, _Type, {Fd, FileName}, LogWrapSize) -> case wrap_p(FileName, LogWrapSize) of true -> file:close(Fd), Old = [FileName, ".old"], file:delete(Old), file:rename(FileName, Old), {ok, Fd2} = file:open(FileName, [write, raw]), {Fd2, FileName}; false -> {Fd, FileName}; enoent -> %% Logfile disappeared, error_logger:format("Logfile ~p disappeared - we reopen it", [FileName]), file:close(Fd), {ok, Fd2} = file:open(FileName, [write, raw]), {Fd2, FileName} end. write_log(ServerName, Type, {Fd, _FileName}, Infos) -> gen_server:cast(yaws_log, {ServerName, Type, Fd, Infos}). %%%---------------------------------------------------------------------- %%% Callback functions from gen_server %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %%---------------------------------------------------------------------- init([]) -> process_flag(trap_exit, true), ets:new(yaws_log, [named_table, set, protected, {keypos, 2}]), {ok, #state{running = false, now = fmtnow()}}. %%---------------------------------------------------------------------- %% Func: handle_call/3 %% Returns: {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_call({setup, GC, Sconfs}, _From, State) when State#state.running == false -> Dir = GC#gconf.logdir, ?Debug("setup ~s~n", [Dir]), ElogFile = filename:join([Dir, "report.log"]), Copy = if ?gc_has_copy_errlog(GC) -> gen_event:add_handler(error_logger, yaws_log_file_h, ElogFile), true; true -> false end, SCs = lists:flatten(Sconfs), lists:foreach(fun(SC) -> yaws_logger:open_log(SC, auth, Dir), yaws_logger:open_log(SC, access, Dir) end, SCs), S2 = State#state{running = true, dir = Dir, now = fmtnow(), log_wrap_size = GC#gconf.log_wrap_size, copy_errlog = Copy, resolve_hostnames = ?gc_log_has_resolve_hostname(GC)}, yaws:ticker(3000, secs3), if is_integer(GC#gconf.log_wrap_size) -> yaws:ticker(10 * 60 * 1000, minute10); true -> ok end, {reply, ok, S2}; %% We can't ever change logdir, we can however %% change logging opts for various servers handle_call({setup, GC, Sconfs}, _From, State) when State#state.running == true -> Dir = State#state.dir, ElogFile = filename:join([Dir, "report.log"]), Copy = if ?gc_has_copy_errlog(GC), State#state.copy_errlog == false-> gen_event:add_handler(error_logger, yaws_log_file_h, ElogFile), true; ?gc_has_copy_errlog(GC) -> true; State#state.copy_errlog == true -> gen_event:delete_handler(error_logger, yaws_log_file_h, normal), false; true -> false end, %% close all files yaws_logger:close_logs(), %% reopen logfiles SCs = lists:flatten(Sconfs), lists:foreach(fun(SC) -> yaws_logger:open_log(SC, auth, Dir), yaws_logger:open_log(SC, access, Dir) end, SCs), S2 = State#state{running = true, dir = Dir, now = fmtnow(), log_wrap_size = GC#gconf.log_wrap_size, copy_errlog = Copy, resolve_hostnames = ?gc_log_has_resolve_hostname(GC)}, if not is_integer(State#state.log_wrap_size), is_integer(GC#gconf.log_wrap_size) -> yaws:ticker(10 * 60 * 1000, minute10); true -> ok end, {reply, ok, S2}; %% a virt server has been added handle_call({soft_add_sc, SC}, _From, State) -> yaws_logger:open_log(SC, auth, State#state.dir), yaws_logger:open_log(SC, access, State#state.dir), {reply, ok, State}; %% a virt server has been deleted handle_call({soft_del_sc, SC}, _From, State) -> yaws_logger:close_log(SC, auth), yaws_logger:close_log(SC, access), {reply, ok, State}; handle_call(state, _From, State) -> {reply, State, State}; handle_call({reopen, Sconfs}, _From, State) -> Dir = State#state.dir, %% close all files yaws_logger:close_logs(), %% reopen logfiles SCs = lists:flatten(Sconfs), lists:foreach(fun(SC) -> yaws_logger:open_log(SC, auth, Dir), yaws_logger:open_log(SC, access, Dir) end, SCs), {reply, ok, State}. %%---------------------------------------------------------------------- %% Func: handle_cast/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_cast({_ServerName, access, Fd, {Ip, Req, InH, OutH, _}}, State) -> case State#state.running of true -> Status = case OutH#outh.status of undefined -> "-"; S -> integer_to_list(S) end, Len = case Req#http_request.method of 'HEAD' -> "-"; _ -> case OutH#outh.contlen of undefined -> case OutH#outh.act_contlen of undefined -> "-"; L -> integer_to_list(L) end; L -> integer_to_list(L) end end, Ver = case Req#http_request.version of {1,0} -> "HTTP/1.0"; {1,1} -> "HTTP/1.1"; {0,9} -> "HTTP/0.9"; _ -> "HTTP/X.X" end, Path = yaws_server:safe_decode_path(Req#http_request.path), Meth = yaws:to_list(Req#http_request.method), Referer = optional_header(InH#headers.referer), UserAgent = optional_header(InH#headers.user_agent), User = case InH#headers.authorization of {U, _P, _OStr} -> U; _ -> "-" end, Msg = fmt_access_log(State#state.now, fmt_ip(Ip, State), User, [Meth, $\s, Path, $\s, Ver], Status, Len, Referer, UserAgent), file:write(Fd, safe_log_data(Msg)), {noreply, State}; false -> {noreply, State} end; handle_cast({ServerName, auth, Fd, {Ip, Path, Item}}, State) -> case State#state.running of true -> Host = fmt_ip(Ip, State), Msg = [Host, " ", State#state.now, " ", ServerName, " " , "\"", Path,"\"", case Item of {ok, User} -> [" OK user=", User]; 403 -> [" 403"]; {401, Realm} -> [" 401 realm=", Realm]; {401, User, PWD} -> [" 401 user=", User, " badpwd=",PWD]; _ -> "" end, "\n"], file:write(Fd, safe_log_data(Msg)), {noreply, State}; false -> {noreply,State} end; handle_cast({yaws_hupped, _}, State) -> handle_info(minute10, State). %%---------------------------------------------------------------------- %% Func: handle_info/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_info(secs3, State) -> {noreply, State#state{now = fmtnow()}}; %% once every 10 minutes, check log sizes handle_info(minute10, State) -> yaws_logger:rotate(State#state.log_wrap_size), case gen_event:call(error_logger, yaws_log_file_h, size, infinity) of {ok, Size} when State#state.log_wrap_size > 0, Size > State#state.log_wrap_size -> gen_event:call(error_logger, yaws_log_file_h, wrap, infinity); {error, enoent} -> gen_event:call(error_logger, yaws_log_file_h, reopen, infinity); _ -> ok end, {noreply, State}; handle_info({'EXIT', _, _}, State) -> {noreply, State}. wrap_p(Filename, LogWrapSize) -> case file:read_file_info(Filename) of {ok, FI} when FI#file_info.size > LogWrapSize, LogWrapSize > 0 -> true; {ok, _FI} -> false; {error, enoent} -> enoent; _ -> false end. %%---------------------------------------------------------------------- %% Func: terminate/2 %% Purpose: Shutdown the server %% Returns: any (ignored by gen_server) %%---------------------------------------------------------------------- terminate(_Reason, _State) -> gen_event:delete_handler(error_logger, yaws_log_file_h, normal), yaws_logger:close_logs(), ok. %%---------------------------------------------------------------------- %% Func: code_change/3 %% Purpose: Handle upgrade %% Returns: new State data %%---------------------------------------------------------------------- code_change(_OldVsn, Data, _Extra) -> {ok, Data}. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- optional_header(Item) -> case Item of undefined -> "-"; Item -> Item end. fmt_access_log(Time, Host, User, Req, Status, Length, Referrer, UserAgent) -> [Host, " - ", User, [$\s], Time, [$\s, $\"], no_ctl(Req), [$\",$\s], Status, [$\s], Length, [$\s,$"], Referrer, [$",$\s,$"], UserAgent, [$",$\n]]. %% Odd security advisory that only affects webservers where users are %% somehow allowed to upload files that later can be downloaded. no_ctl([H|T]) when H < 32 -> no_ctl(T); no_ctl([H|T]) -> [H|no_ctl(T)]; no_ctl([]) -> []. fmt_ip(IP, State) when is_tuple(IP) -> case State#state.resolve_hostnames of true -> case catch inet:gethostbyaddr(IP) of {ok, HE} -> HE#hostent.h_name; _ -> case catch inet_parse:ntoa(IP) of {'EXIT', _} -> "unknownip"; Addr -> Addr end end; false -> case catch inet_parse:ntoa(IP) of {'EXIT', _} -> "unknownip"; Addr -> Addr end end; fmt_ip(unknown, _) -> "unknownip"; fmt_ip(undefined, _) -> "0.0.0.0"; fmt_ip(HostName, _) -> HostName. fmtnow() -> {{Year, Month, Day}, {Hour, Min, Sec}} = calendar:now_to_local_time(yaws:get_time_tuple()), ["[",fill_zero(Day,2),"/",yaws:month(Month),"/",integer_to_list(Year),":", fill_zero(Hour,2),":",fill_zero(Min,2),":", fill_zero(Sec,2)," ",zone(),"]"]. zone() -> Time = erlang:universaltime(), LocalTime = calendar:universal_time_to_local_time(Time), DiffSecs = calendar:datetime_to_gregorian_seconds(LocalTime) - calendar:datetime_to_gregorian_seconds(Time), zone(DiffSecs div 3600, (DiffSecs rem 3600) div 60). zone(Hr, Min) when Hr < 0; Min < 0 -> [$-, fill_zero(abs(Hr), 2), fill_zero(abs(Min), 2)]; zone(Hr, Min) when Hr >= 0, Min >= 0 -> [$+, fill_zero(abs(Hr), 2), fill_zero(abs(Min), 2)]. fill_zero(N, Width) -> left_fill(N, Width, $0). left_fill(N, Width, Fill) when is_integer(N) -> left_fill(integer_to_list(N), Width, Fill); left_fill(N, Width, _Fill) when length(N) >= Width -> N; left_fill(N, Width, Fill) -> left_fill([Fill|N], Width, Fill). safe_log_data(Elements) -> [ yaws:to_string(E) || E <- Elements ]. yaws-2.0.2/src/yaws_appmod_dav.erl0000664000175000017500000013132012605311412014064 00000000000000%%%------------------------------------------------------------------- %%% File : yaws_appmod_dav.erl %%% Created : 11 Nov 2012 %%% Purpose : WebDav module, RFC4918 class 1, 2, 3 compliant %%% %%% To use, add the following configuration: %%% %%% %%% ... %%% dav = true %%% %%% %%% This configuration is short for: %%% %%% runmod = yaws_runmod_lock %%% ... %%% %%% ... %%% appmods = %%% %%% %%% Todo : 1) Add header handling (most of the time not used by DAV %%% clients): %%% If-Match, If-Modified-Since, If-None-Match, %%% If-Range, If-Unmodified-Since, TE %%% 2) POST on collections %%%------------------------------------------------------------------- -module(yaws_appmod_dav). %% for appmod: -export([out/1]). %% for replacement xmerl_xml: -export([export/1]). -import(xmerl_lib, [markup/3, empty_tag/2, export_text/1]). -ifdef(debug). -define(DEBUG(X), io:format(X)). -define(DEBUG(X,Y), io:format(X,Y)). -else. -define(DEBUG(X), true). -define(DEBUG(X,Y), true). -endif. -include("../include/yaws_dav.hrl"). -include("../include/yaws_lock.hrl"). -include("../include/yaws_api.hrl"). -include("../include/yaws.hrl"). -include("yaws_debug.hrl"). -include_lib("xmerl/include/xmerl.hrl"). -include_lib("kernel/include/file.hrl"). out(A) -> try h_litmus(A), %% handle the request R = A#arg.req, Method = R#http_request.method, H = A#arg.headers, C = if H#headers.user_agent == undefined -> standard; true -> Ms = string:str(H#headers.user_agent,"Microsoft"), if Ms > 0 -> microsoft; true -> standard end end, put(compatibility,C), handle(Method,A) catch {Status,Precondition} -> Response1 = [{'D:error', [{'xmlns:D',"DAV:"}], [{Precondition,[],[]}]}], status(Status,{xml,Response1}); Status -> status(Status); _Error:{noproc,{gen_server,call,[yaws_runmod_lock|_Whatever]}} -> Msg = "Lock server not started. See documentation.~n", error_logger:error_msg(Msg), Response = [{'D:error',[{'xmlns:D',"DAV:"}],[Msg]}], status(500,{xml,Response}); _Error:Reason -> error_logger:info_msg("unexpected error: ~p~n~p~n", [Reason,erlang:get_stacktrace()]), Response = [{'D:error',[{'xmlns:D',"DAV:"}],[Reason]}], status(500,{xml,Response}) end. %%------------------------------------------------------ %% handle methods %% handle('OPTIONS',A) -> ?DEBUG("OPTIONS"), R = davresource0(A), F = R#resource.info, T = case F#file_info.type of directory -> "httpd/unix-directory"; _ -> Name = R#resource.name, Ext = filename:extension(Name), Ext1 = case Ext of [] -> ""; _ -> tl(Ext) end, {_Kind,Mimetype} = mime_types:t(Ext1), Mimetype end, Headers = [{header,{"Allow", "GET, POST, OPTIONS, HEAD, PUT, DELETE, " "PROPFIND, PROPPATCH, LOCK, UNLOCK, " "MKCOL, MOVE, COPY"}}], status(200,[{header,{"Content-Type",T}}|Headers],[]); handle('HEAD',A) -> ?DEBUG("HEAD ~p",[A#arg.server_path]), Path = davpath(A), case file:read_file_info(Path) of {ok, F} when (F#file_info.type == regular) -> E = yaws:make_etag(F), Name = A#arg.server_path, Ext = filename:extension(Name), Ext1 = case Ext of [] -> ""; _ -> tl(Ext) end, {_Kind,T} = mime_types:t(Ext1), status(200,[{header,{"Etag",E}},{header,{"Content-Type",T}}]); {ok, F} when (F#file_info.type == directory) -> status(200,[{header,{"Content-Type","httpd/unix-directory"}}]); _ -> throw(404) end; handle('GET',A) -> ?DEBUG("GET ~p",[A#arg.server_path]), Name = A#arg.server_path, Path = A#arg.fullpath, Pid = self(), SC=get(sc), PPS = SC#sconf.partial_post_size, case file:read_file_info(Path) of {ok,F} when F#file_info.type==directory -> {ok,Dir} = file:list_dir(Path), Listing = lists:foldl( fun(Fname,L) -> {ok,Finfo} = file:read_file_info( filename:join(Path,Fname)), Ftype = case Finfo#file_info.type of directory -> "Coll:"; _ -> " " end, Fsize = integer_to_list(Finfo#file_info.size), Ftime = yaws:local_time_as_gmt_string( Finfo#file_info.mtime), Entry = io_lib:format("~s ~-20s ~10s ~s~n", [Ftype,Fname,Fsize,Ftime]), L++Entry end,"",lists:sort(Dir)), Response = {ehtml,[ {html,[],[ {head,[],[ {title,[],Name}] }, {body,[],[ {h2,[],"Index of "++Name}, {pre,[],Listing}] }] }] }, status(200,Response); {ok,F} -> Size = integer_to_list(F#file_info.size), Ext = filename:extension(Name), Ext1 = case Ext of [] -> ""; _ -> tl(Ext) end, {_Kind,Mimetype} = mime_types:t(Ext1), H = [{header,{"Content-Length",Size}}], {ok,Fd} = file:open(Path,[read,binary]), case file:read(Fd,PPS) of {ok,Data} when size(Data) ?DEBUG("only chunk~n"), status(200,H,{content,Mimetype,Data}); {ok,Data} -> ?DEBUG("first chunk~n"), spawn(fun() -> deliver_rest(Pid,Fd) end), status(200,H,{streamcontent,Mimetype,Data}); eof -> status(200,{content,"application/octet-stream",<<>>}); {error,Reason} -> Response = [{'D:error',[{'xmlns:D',"DAV:"}],[Reason]}], status(500,{xml,Response}) end; {error,enoent} -> status(404); _Other -> status(500) end; handle('POST',A) -> ?DEBUG("POST ~p",[A#arg.server_path]), _Path = davpath(A), %% TODO POST for collections: RFC5995 status(501); handle("LOCK",A) -> %% TODO Multi resource lock (lock on collection) returns 207 %% (multi-status) when failing ?DEBUG("LOCK ~p",[A#arg.server_path]), Name = A#arg.server_path, Path = davpath(A), %% check if file/collection exists and create if not so %% RFC4918 - 9.10.4 {Status,R} = case file:read_file_info(Path) of {ok, F} when (F#file_info.type == directory) or (F#file_info.type == regular) -> {200,#resource{ name = Name, info = F}}; {error,enoent} -> case string:right(A#arg.server_path,1) of "/" -> ok = file:make_dir(Path); _ -> ok = file:write_file(Path,"") end, {ok, F} = file:read_file_info(Path), {201,#resource{ name = Name, info = F}}; {error,_} -> throw(409) end, Req = binary_to_list(A#arg.clidata), L = parse_lockinfo(Req), %%Id = h_locktoken(A), Timeout = h_timeout(A), Depth = h_depth(A), Id = h_if_refresh(A,Path), case yaws_runmod_lock:lock(Path,L#lock{path=Path,id=Id,timeout=Timeout, depth=Depth}) of {ok,Id1} -> {200,Result} = prop_get({'DAV:',lockdiscovery},A,R), Response = [{'D:prop', [{'xmlns:D',"DAV:"}], [Result]}], status(Status,[{header, {"Lock-Token",""}}], {xml,Response}); {error,locked} -> status(423); _ -> throw(501) end; handle("UNLOCK",A) -> ?DEBUG("UNLOCK ~p",[A#arg.server_path]), Path = davpath(A), Id = h_locktoken(A), %%?DEBUG(" Id=~p",[Id]), case yaws_runmod_lock:unlock(Path,Id) of ok -> status(204); not_found -> Response = [{'D:error', [{'xmlns:D',"DAV:"}], [{'lock-token-matches-request-uri',[],[]}]}], status(409,{xml,Response}) end; handle('DELETE',A) -> ?DEBUG("DELETE ~p",[A#arg.server_path]), Path = davpath(A), h_if(A,Path), R = davresource0(A), %% use internal locking to be safe case yaws_runmod_lock:lock(R#resource.name, #lock{depth=infinity,scope=exclusive}) of {ok,Id} -> F = filename:join(A#arg.docroot,["./",R#resource.name]), fs_rmrf(F), yaws_runmod_lock:unlock(R#resource.name,Id), status(200); _ -> throw(423) end; handle('PUT',A) when A#arg.state == undefined -> ?DEBUG("PUT ~p",[A#arg.server_path]), Path = davpath(A), h_if(A,Path), case filelib:is_dir(Path) of true -> throw(405); false -> TmpName = temp_name(Path), X = file:open(TmpName, [raw,write]), case X of {ok, Fd} -> State = #upload{fd=Fd, filename=Path, tempname=TmpName}, case A#arg.clidata of {partial,Bin} -> file:write(Fd,Bin), {get_more,<<>>,State}; Bin -> file:write(Fd,Bin), file:close(Fd), case file:rename(TmpName, Path) of ok -> status(201); _ -> status(409) end end; {error,eexist} -> throw(405); {error,enoent} -> throw(409); {error,eisdir} -> throw(409); {error,enospace} -> throw(507); _ -> status(500) end end; handle('PUT',A) -> State = A#arg.state, Fd = State#upload.fd, case A#arg.clidata of {partial,Bin} -> file:write(Fd,Bin), {get_more,<<>>,State}; Bin -> file:write(Fd,Bin), file:close(Fd), FName = State#upload.filename, TmpName = State#upload.tempname, case file:rename(TmpName, FName) of ok -> status(201); _ -> status(409) % TODO delete temp file here? end end; handle("MKCOL",A) -> ?DEBUG("MKCOL ~p",[A#arg.server_path]), Path = davpath(A), if %% RFC2518, 8.3.1 size(A#arg.clidata) > 0 -> throw(415); true -> ok end, h_if(A,Path), file_do(make_dir,[Path]), status(201); handle("COPY",A) -> ?DEBUG("COPY ~p",[A#arg.server_path]), From = A#arg.fullpath, Dest = h_destination(A), To = case {string:right(Dest,1),string:right(Dest,1)} of {"/",_} -> Dest; {_,"/"} -> filename:join(Dest,filename:basename(From)); _ -> Dest end, DoOverwrite = h_overwrite(A), ToExists = exists(To), if DoOverwrite == false, ToExists == true -> status(412); true -> if ToExists == true -> h_if(A,To), fs_rmrf(To), fs_cp(From,To), status(204); true -> fs_cp(From,To), status(201) %%status(201,[{'Location',To}],[]) end end; handle("MOVE",A) -> ?DEBUG("MOVE ~p",[A#arg.server_path]), From = davpath(A), h_if(A,From), Dest = h_destination(A), To = case {string:right(Dest,1),string:right(Dest,1)} of {"/",_} -> Dest; {_,"/"} -> filename:join(Dest,filename:basename(From)); _ -> Dest end, DoOverwrite = h_overwrite(A), ToExists = exists(To), if DoOverwrite == false, ToExists == true -> status(412); true -> if ToExists == true -> h_if(A,To), fs_rmrf(To); true -> ok end, case file:rename(From, To) of ok when ToExists == true -> status(204); ok -> status(201); _ -> try fs_cp(From, To), fs_rmrf(From), status(201) catch throw:Status -> ?DEBUG(" move from ~p to ~p failed: ~p\n", [From, To, Status]), Response = [{'D:error', [{'xmlns:D',"DAV:"}], [Status]}], status(Status,{xml,Response}) end end end; handle("PROPFIND",A) -> ?DEBUG("PROPFIND ~p",[A#arg.server_path]), Req = binary_to_list(A#arg.clidata), Props = parse_propfind(Req), R = davresource0(A), case h_depth(A) of 0 -> Response = {'D:response', [], propfind_response(Props,A,R)}, MultiStatus = [{'D:multistatus', [{'xmlns:D',"DAV:"}], [Response]}], status(207,{xml,MultiStatus}); 1 -> R1 = davresource1(A), Response = {'D:response', [], propfind_response(Props,A,R)}, Responses = [{'D:response', [], propfind_response(Props,A,Rx)} || Rx <- R1], MultiStatus = [{'D:multistatus', [{'xmlns:D',"DAV:"}], [Response|Responses]}], status(207,{xml,MultiStatus}); infinity -> Response = [{'D:error', [{'xmlns:D',"DAV:"}], [{'propfind-finite-depth',[],[]}]}], status(403,{xml,Response}) end; handle("PROPPATCH",A) -> ?DEBUG("PROPPATCH ~p",[A#arg.server_path]), Path = davpath(A), h_if(A,Path), Req = binary_to_list(A#arg.clidata), R = davresource0(A), Update = parse_proppatch(Req), Response = {'D:response',[],proppatch_response(Update,A,R)}, MultiStatus = [{'D:multistatus', [{'xmlns:D',"DAV:"}], [Response]}], status(207,{xml,MultiStatus}); handle(_Other,_A) -> status(405). %% -------------------------------------------------------- %% File functions %% %% deliver chunked data deliver_rest(Pid,Fd) -> case file:read(Fd,10240) of {ok, Data} -> yaws_api:stream_chunk_deliver(Pid,Data), deliver_rest(Pid,Fd); eof -> yaws_api:stream_chunk_end(Pid), file:close(Fd); {error,Reason} -> exit(Reason) end. %% do a recoverable/catchable file function file_do(Func,Params) -> Result = erlang:apply(file,Func,Params), case Result of ok -> ok; {ok,X} -> {ok,X}; {ok,X1,X2} -> {ok,X1,X2}; eof -> eof; {error,eexist} -> throw(405); {error,enoent} -> throw(409); {error,eisdir} -> throw(409); {error,enospace} -> throw(507); _Error -> ?DEBUG("file function returned ~p~n",[_Error]),throw(500) end. %% recursive remove, equivalent of rm -rf fs_rmrf(Path) -> {ok, F} = file_do(read_file_info,[Path]), case F#file_info.type of directory -> {ok, Dir} = file_do(list_dir,[Path]), [ fs_rmrf(filename:join(Path,File)) || File <- Dir ], ok = file:del_dir(Path); %%file_do(del_dir,[Path]); _ -> ok = file:delete(Path) %%file_do(delete,[Path]) end. %% recursive copy, equivalent of cp fs_cp(From,To) -> %% All checks on existence of the destination have to be done before %% so destination should not exist {ok, F} = file:read_file_info(From), case F#file_info.type of directory -> file_do(make_dir,[To]), {ok, Dir} = file:list_dir(From), [ fs_cp(filename:join(From,File),filename:join(To,File)) || File <- Dir ]; _ -> file_do(copy,[From,To]) end. %% check existence exists(Path) -> case file:read_file_info(Path) of {ok, _} -> true; _ -> false end. %% generate a temporary filename as a dotted file with a timestamp temp_name(F) -> {A,B,C} = yaws:get_time_tuple(), Path = filename:dirname(F), File = filename:basename(F), T0 = io_lib:format("~s/.~s.~p-~p-~p",[Path,File,A,B,C]), lists:flatten(T0). %% -------------------------------------------------------- %% Property functions %% %% propfind response propfind_response(Props,A,R) -> Url = yaws_api:url_encode(R#resource.name), case Props of [allprop] -> AllProp = [ prop_get(N,A,R) || N <- allprops(R) ], AllSorted = prop_sort(AllProp), {200, Results} = lists:keyfind(200,1,AllSorted), [{'D:href', [], [Url]}, {'D:propstat', [], [ {'D:prop', [], Results},{status, [],["HTTP/1.1 200 OK"]} ]}]; [propname] -> Results = [ case NS of 'DAV:' -> {list_to_atom("D:"++atom_to_list(P)),[],[]}; _ -> {P,[{'xmlns',NS}],[]} end || {NS,P} <-allprops(R) ], [{'D:href', [], [Url]}, {'D:propstat', [], [ {'D:prop', [], Results},{status, [],["HTTP/1.1 200 OK"]} ]}]; PropsRequested -> Results = [ prop_get(N,A,R) || {N,_} <- PropsRequested ], ResultsSorted = prop_sort(Results), [{'D:href', [], [Url]}| [{'D:propstat', [], [ {'D:prop', [], PropsFound},prop_status(Status) ]} || {Status,PropsFound} <- ResultsSorted ] ] end. %% proppatch response/ proppatch_response(Update,A,R) -> Url = yaws_api:url_encode(R#resource.name), Results = proppatch_response(Update,A,R,[]), ResultsSorted = prop_sort(lists:flatten(Results)), [{'D:href', [], [Url]}| [{'D:propstat', [], [ {'D:prop', [], PropsFound},prop_status(Status) ]} || {Status,PropsFound} <- ResultsSorted ] ]. proppatch_response([H|T],A,R,Results) -> Result = case H of {set,Props} -> [ prop_set(P,A,R,V) || {P,V} <- Props]; {remove,Props} -> [ prop_remove(P,A,R) || {P,_V} <- Props] end, proppatch_response(T,A,R,[Result|Results]); proppatch_response([],_A,_R,Results) -> Results. prop_sort(L) -> prop_sort(L,[]). prop_sort([H|T],R) -> {Status,Prop} = H, R1 = case lists:keyfind(Status,1,R) of {Status, Props} -> lists:keystore(Status,1,R,{Status,[Prop|Props]}); false -> lists:keystore(Status,1,R,{Status,[Prop]}) end, prop_sort(T,R1); prop_sort([],R) -> R. prop_status(Status) -> {'D:status',[],["HTTP/1.1 " ++ integer_to_list(Status) ++ " " ++ yaws_api:code_to_phrase(Status)]}. %% Available props include namespace %% Available props can differ per resource %% For proposed Microsoft extensions see: draft-hopmann-collection-props-00.txt %% allprops(R) -> F = R#resource.info, C = get(compatibility), %% default property set P1 = [ {'http://yaws.hyber.org/',access}, % sample Yaws extension {'DAV:',creationdate}, %%{'DAV:',getcontentlanguage}, % not supported in GET % so omitted here as well {'DAV:',getcontentlength}, {'DAV:',getcontenttype}, {'DAV:',getetag}, {'DAV:',getlastmodified}, {'DAV:',lockdiscovery}, % class 2 compliancy %%{'DAV:','quota-avialable-bytes'} % RFC4331 %{'DAV:','quota-used-bytes'} % RFC4331 {'DAV:',resourcetype}, {'DAV:',supportedlock} % class 2 compliancy ], %% properties depending on file type P2 = case F#file_info.type of directory when C==windows -> [ {'DAV:',childcount} % Microsoft extension ]; %% The executable property is only shown for regular files regular -> [ {'http://apache.org/dav/props/',executable} % Apache extension ]; _ -> [ ] end, %% compatibility properties P3 = case C of microsoft -> [ %%{'DAV:',iscollection}, {'DAV:',isfolder}, {'DAV:',ishidden} %%{'DAV:',isreadonly}, %%{'DAV:',isroot}, %%{'DAV:',name}, ]; _ -> [ {'DAV:',displayname} ] end, P1++P2++P3. prop_get({'http://yaws.hyber.org/',access},_A,R) -> F = R#resource.info, A = F#file_info.access, P = {access, [{xmlns,'http://yaws.hyber.org/'}], [atom_to_list(A)]}, {200, P}; prop_get({'DAV:',childcount},A,_R) -> Path=davpath(A), L = case file:list_dir(Path) of {ok, Files} -> length(Files); _ -> 0 end, P = {'D:childcount', [], [integer_to_list(L)]}, {200, P}; prop_get({'DAV:',creationdate},_A,R) -> F = R#resource.info, D = F#file_info.ctime, T = yaws:local_time_as_gmt_string(D), P = {'D:creationdate', [], [lists:flatten(T)]}, {200, P}; prop_get({'DAV:',displayname},_A,R) -> case get(compatibility) of microsoft -> {404,{'D:displayname',[],[]}}; _ -> Name = filename:basename(R#resource.name), Xml = #xmlText{type=cdata,value=Name}, P = {'D:displayname', [], [Xml]}, {200, P} end; prop_get({'http://apache.org/dav/props/',executable},_A,R) -> F = R#resource.info, case F#file_info.type of directory -> {404,{executable, [{'xmlns',"http://apache.org/dav/props/"}], []}}; _ -> %% TODO check on extension for Windows? X = case F of #file_info{mode=Mode} when Mode band 8#111 =/= 0 -> "T"; _ -> "F" end, {200, {executable, [{'xmlns',"http://apache.org/dav/props/"}], X}} end; prop_get({'DAV:',getcontentlanguage},_A,_R) -> P = {'D:getcontentlanguage', [], []}, {200, P}; prop_get({'DAV:',getcontentlength},_A,R) -> F = R#resource.info, P = {'D:getcontentlength', [], [integer_to_list(F#file_info.size)]}, {200, P}; prop_get({'DAV:',getcontenttype},_A,R) -> F = R#resource.info, Mediatype = case F#file_info.type of directory -> "httpd/unix-directory"; %%"text/html"; %% this should represent the mediatype of a GET on a collection _ -> Name = R#resource.name, Ext = filename:extension(Name), Ext1 = case Ext of [] -> ""; _ -> tl(Ext) end, {_Kind,Mimetype} = mime_types:t(Ext1), Mimetype end, P = {'D:getcontenttype', [], [Mediatype]}, {200, P}; prop_get({'DAV:',getetag},_A,R) -> F = R#resource.info, E = yaws:make_etag(F), P = {'D:getetag', [], [E]}, {200, P}; prop_get({'DAV:',getlastmodified},_A,R) -> F = R#resource.info, D = F#file_info.mtime, T = yaws:local_time_as_gmt_string(D), X = lists:flatten(T), C = get(compatibility), P = case C of microsoft -> {'getlastmodified', [{'xmlns:b', "urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/"}, {'b:dt',"dateTime.rfc1123"}],[X]}; _ -> {'D:getlastmodified',[],[X]} end, {200, P}; prop_get({'DAV:',isfolder},_A,R) -> F = R#resource.info, D = case F#file_info.type of directory -> "1"; _ -> "0" end, P = {'D:isfolder', [], [D]}, {200, P}; prop_get({'DAV:',ishidden},_A,R) -> N = filename:basename(R#resource.name), H = case N of "."++_Rest -> "1"; % dotted file _ -> "0" end, P = {'D:ishidden', [], [H]}, {200, P}; prop_get({'DAV:',resourcetype},_A,R) -> F = R#resource.info, P = case F#file_info.type of directory -> {'D:resourcetype', [], [{'D:collection',[],[]}]}; _ -> {'D:resourcetype', [], []} end, {200, P}; prop_get({'DAV:',lockdiscovery},A,_R) -> Path = davpath(A), Locks = yaws_runmod_lock:discover(Path), case Locks of [] -> {404,{'D:lockdiscovery',[],[]}}; _ -> ActiveLocks = [{'D:activelock',[], [{'D:lockscope',[],[prop_get_format(scope,Lock#lock.scope)]}, {'D:locktype',[],[prop_get_format(type,Lock#lock.type)]}, {'D:depth',[],[prop_get_format(depth,Lock#lock.depth)]}, {'D:owner',[],[prop_get_format(owner,Lock#lock.owner)]}, {'D:timeout',[],[prop_get_format(timeout,Lock#lock.timeout)]}, {'D:locktoken',[],[prop_get_format(locktoken,Lock#lock.id)]}, {'D:lockroot',[],[prop_get_format(lockroot,Lock#lock.path)]} ]} || Lock <- Locks ], {200, {'D:lockdiscovery',[],ActiveLocks}} end; prop_get({'DAV:',supportedlock},_A,_R) -> P = {'D:supportedlock',[],[ {'D:lockentry',[],[ {'D:lockscope',[],[{'D:exclusive',[],[]}]}, {'D:locktype',[],[{'D:write',[],[]}]} ]}, {'D:lockentry',[],[ {'D:lockscope',[],[{'D:shared',[],[]}]}, {'D:locktype',[],[{'D:write',[],[]}]} ]} ]}, {200, P}; prop_get({'',_P},_A,_R) -> throw(400); prop_get({NS,P},_A,_R) -> {404,{P,[{'xmlns',NS}],[]}}. prop_set({'DAV:',creationdate},A,_R,V) -> Path=davpath(A), P = {'D:creationdate', [], []}, case file:read_file_info(Path) of {ok,F0} -> T = yaws:stringdate_to_datetime(V), F1 = F0#file_info{ctime=T}, case file:write_file_info(Path,F1) of ok -> {200, P}; {error,_} -> {409, P} end; {error,_} -> {409, P} end; prop_set({'DAV:',getlastmodified},A,_R,V) -> Path=davpath(A), P = {'D:getlastmodified', [], []}, case file:read_file_info(Path) of {ok,F0} -> T = yaws:stringdate_to_datetime(V), F1 = F0#file_info{mtime=T}, case file:write_file_info(Path,F1) of ok -> {200, P}; {error,_} -> {409, P} end; {error,_} -> {409, P} end; %%prop_set({'http://apache.org/dav/props/',executable},_A,R,_V) -> %% {501,{P,[{'xmlns',NS}],[]}}; % Not yet implemented prop_set({'DAV:',getetag},_A,_R,_V) -> {403,{'D:getetag',[],[{'cannot-modify-protected-property',[],[]}]}}; prop_set({'DAV:',lockdiscovery},_A,_R,_V) -> {403,{'D:lockdiscovery',[],[{'cannot-modify-protected-property',[],[]}]}}; prop_set({'DAV:',resourcetype},_A,_R,_V) -> {403,{'D:resourcetype',[],[{'cannot-modify-protected-property',[],[]}]}}; prop_set({NS,P},_A,_R,_V) -> {404,{P,[{'xmlns',NS}],[]}}. prop_remove({P,NS},_A,_R) -> {403,{P,[{'xmlns',NS}],[]}}. prop_get_format(type,write) -> {'D:write',[],[]}; prop_get_format(scope,exclusive) -> {'D:exclusive',[],[]}; prop_get_format(scope,_) -> {'D:shared',[],[]}; prop_get_format(depth,infinity) -> "infinity"; prop_get_format(depth,Depth) -> integer_to_list(Depth); prop_get_format(timeout,Timeout) -> lists:flatten(io_lib:format("Second-~p",[Timeout])); prop_get_format(locktoken,Id) -> {'D:href',[],["opaquelocktoken:"++Id]}; prop_get_format(lockroot,Ref) -> {'D:href',[],[Ref]}; prop_get_format(owner,Owner) -> Owner; prop_get_format(_Something,_) -> ?DEBUG(" did not expect ~p here ~n",[_Something]), throw(500). %% -------------------------------------------------------- %% Resource mapping %% davname(A) -> A#arg.server_path. davpath(A) -> filename:join(A#arg.docroot,["./",A#arg.server_path]). %% davresource0/1 - get resources with depth 0 davresource0(A) -> Name = davname(A), Path = davpath(A), case file:read_file_info(Path) of {ok, F} when (F#file_info.type == directory) or (F#file_info.type == regular) -> #resource{ name = Name, info = F}; {error,_} -> throw(404) end. %% davresource1/1 - get additional resources for depth 1 davresource1(A) -> Coll = davname(A), Path = davpath(A), case file:read_file_info(Path) of {ok, Dir} when Dir#file_info.type == directory -> {ok, L} = file:list_dir(Path), davresource1(A,Path,Coll,L,[]); {ok, _Else} -> [] end. davresource1(_A,_Path,_Coll,[],Result) -> Result; davresource1(_A,Path,Coll,[Name|Rest],Result) -> File = filename:join(Path,Name), Ref = filename:join(Coll,Name), {ok, Info} = file:read_file_info(File), if (Info#file_info.type == regular) or (Info#file_info.type == directory) -> Resource = #resource {name = Ref, info = Info}, davresource1(_A,Path,Coll,Rest,[Resource|Result]); true -> davresource1(_A,Path,Coll,Rest,Result) end. %% -------------------------------------------------------- %% Parse additional HTTP headers %% h_litmus(A) -> Hs = (A#arg.headers)#headers.other, case lists:keysearch("X-Litmus", 3, Hs) of {value, {_,_,"X-Litmus",_,_Test}} -> ?DEBUG("~s - ",[_Test]); _ -> ok end. h_depth(A) -> Hs = (A#arg.headers)#headers.other, case lists:keysearch("Depth", 3, Hs) of {value, {_,_,"Depth",_,Depth}} -> h_depth_interpret(Depth); _ -> infinity end. h_depth_interpret("infinity") -> infinity; h_depth_interpret("1") -> 1; h_depth_interpret(_) -> 0. h_destination(A) -> Hs = (A#arg.headers)#headers.other, case lists:keysearch("Destination", 3, Hs) of {value, {http_header,_,_,_,Dest}} -> Url = yaws_api:parse_url(Dest), {Path,_} = yaws_api:url_decode_q_split(Url#url.path), ?DEBUG(" TO ~p",[Path]), filename:join(A#arg.docroot,["./",Path]); _ -> throw(501) end. h_overwrite(A) -> Hs = (A#arg.headers)#headers.other, case lists:keysearch("Overwrite", 3, Hs) of {value, {http_header, _ , _, _, "T"}} -> true; _ -> false end. h_timeout(A) -> Hs = (A#arg.headers)#headers.other, case lists:keysearch("Timeout", 3, Hs) of {value, {_,_,"Timeout",_,T}} -> case T of "Second-"++TimeoutVal -> Val = case catch list_to_integer(TimeoutVal) of I when is_integer(I) -> I; _ -> ?LOCK_LIFETIME end, erlang:min(Val,?LOCK_LIFETIME); _ -> ?LOCK_LIFETIME end; _ -> ?LOCK_LIFETIME end. h_locktoken(A) -> Hs = (A#arg.headers)#headers.other, C = get(compatibility), case lists:keysearch("Lock-Token", 3, Hs) of {value, {_,_,"Lock-Token",_,URL}} -> case URL of %%" string:left(Token,36); " T = parse_locktoken(Token), check_locktoken_format(T), T; "opaquelocktoken:"++Token when C==microsoft -> Token; _ -> URL end; _ -> undefined end. parse_locktoken([]) -> []; parse_locktoken([H|_T]) when H==62 -> []; parse_locktoken([H|T]) -> [H|parse_locktoken(T)]. check_locktoken_format("DAV:no-lock") -> ok; check_locktoken_format(Token) when length(Token)==36 -> ok; check_locktoken_format(_Token) -> throw(423). %%h_if_match(A,Path) -> %% Hs = (A#arg.headers)#headers.other, %% case lists:keysearch("If-Match", 3, Hs) of %% {value, {_,_,"If-Match",_,Tag}} -> %% F = file:read_file_info(Path), %% case yaws:make_etag(F) of %% Tag -> ok; %% _ -> throw(412) %% end; %% _ -> %% ok %% end. h_if_refresh(A,Path) -> ?DEBUG(" If(~p)",[Path]), _Locks = yaws_runmod_lock:discover(Path), Hs = (A#arg.headers)#headers.other, case lists:keysearch("If", 3, Hs) of {value, {_,_,"If",_,If}} -> List = if_parse(If,untagged), %%?DEBUG(" ~p",[List]), case List of [{_Resource,[{true,state,Locktoken}]}] -> Locktoken; _ -> throw(412) end; _ -> undefined end. h_if(A,Path) -> ?DEBUG(" If(~p)",[Path]), Locks = yaws_runmod_lock:discover(Path), Hs = (A#arg.headers)#headers.other, {_L,I} = case lists:keysearch("If", 3, Hs) of {value, {_,_,"If",_,If}} -> List = if_parse(If,untagged), Value = if_eval(A,Locks,List), {List,Value}; _ -> {[],undefined} end, ?DEBUG(" -> ~p (~p)",[I,length(Locks)]), ?DEBUG(" If-header ~p (~p) evaluated to ~p~n",[_L,length(Locks),I]), case I of undefined when length(Locks)>0 -> throw(423); %%false when length(Locks)>0 -> throw(412); false -> throw(412); _ -> ok end. if_parse([],_Resource) -> []; if_parse(Line,Resource) when hd(Line)==32 -> if_parse(tl(Line),Resource); if_parse(Line,untagged) when hd(Line)==60 -> % < {Url,Rest} = if_parse_token(tl(Line),""), if_parse(Rest,Url); if_parse(Line,Resource) when hd(Line)==40 -> % ( {Condition,Rest} = if_parse_condition(tl(Line),[],true), [{Resource,Condition}|if_parse(Rest,untagged)]. if_parse_condition(Line,List,_Bool) when hd(Line)==41 -> % ) {List,tl(Line)}; if_parse_condition(Line,List,Bool) when hd(Line)==32 -> % whitespace if_parse_condition(tl(Line),List,Bool); if_parse_condition("Not"++Line,List,_Bool) -> % negate if_parse_condition(tl(Line),List,false); if_parse_condition(Line,List,Bool) when hd(Line)==60 -> % < {Token,Rest} = if_parse_token(tl(Line),""), if_parse_condition(Rest,[{Bool,state,Token}|List],true); if_parse_condition(Line,List,Bool) when hd(Line)==91 -> % [ {Etag,Rest} = if_parse_etag(tl(Line),""), if_parse_condition(Rest,[{Bool,etag,Etag}|List],true). if_parse_token(Line,Buffer) when hd(Line)==62 -> % > Uri = lists:reverse(Buffer), Token1 = case Uri of "opaquelocktoken:"++Token -> check_locktoken_format(Token), Token; _ -> Uri end, {Token1,tl(Line)}; if_parse_token([H|T],Buffer) -> if_parse_token(T,[H|Buffer]). if_parse_etag(Line,Buffer) when hd(Line)==93 -> % ] {lists:reverse(Buffer),tl(Line)}; if_parse_etag([H|T],Buffer) -> if_parse_etag(T,[H|Buffer]). %% if_eval(A,RequestPath,Conditions) if_eval(_A,_Locks,[]) -> false; if_eval(A,Locks,[{Resource,AndList}|More]) -> Target = case Resource of untagged -> davpath(A); _ -> Url = yaws_api:parse_url(Resource), filename:join(A#arg.docroot,["./",Url#url.path]) end, if_eval_condition(AndList,A,Target,Locks) orelse if_eval(A,Locks,More). if_eval_condition(AndList,A,Target,Locks) -> if_eval_condition(AndList,true,false,A,Target,Locks). if_eval_condition([],Result,Valid,_A,_Target,_Locks) -> Result and Valid; if_eval_condition([{false,Kind,Ref}|T],Result,Valid,A,Target,Locks) -> not if_eval_condition([{true,Kind,Ref}|T],Result,Valid,A,Target,Locks); if_eval_condition([{true,state,Ref}|T],_Result,_Valid,A,Target,Locks) -> Result1 = if_eval_locktoken(Target,Ref,Locks), Valid1 = true, Result1 andalso if_eval_condition(T,Result1,Valid1,A,Target,Locks); if_eval_condition([{true,etag,Ref}|T],_Result,Valid,A,Target,Locks) -> {ok, F} = file:read_file_info(filename:join(A#arg.docroot,Target)), E = yaws:make_etag(F), Result1 = (E==Ref), Valid1 = Valid, Result1 andalso if_eval_condition(T,Result1,Valid1,A,Target,Locks). %% if_eval_locktoken(Target,Token,Locktokens) -> true|false if_eval_locktoken(_Target,_Token,[]) -> false; %%if_eval_locktoken(_Target,"DAV:no-lock",[]) -> %% true; if_eval_locktoken(Target,Token,[H|T]) -> ((H#lock.path == Target) and (H#lock.id == Token)) orelse if_eval_locktoken(Target,Token,T). %% -------------------------------------------------------- %% Parsing of XML elements (RFC4918) %% %% activelock -define(IS_ALLPROP(X), #xmlElement{expanded_name = {'DAV:',allprop}} = X). %% collection %% depth %% error -define(IS_EXCLUSIVE(X), #xmlElement{expanded_name = {'DAV:',exclusive}} = X). -define(IS_HREF(X), #xmlElement{expanded_name = {'DAV:',href}} = X). %% include % TODO: add this tag %% location %% lockentry -define(IS_LOCKINFO(X), #xmlElement{expanded_name = {'DAV:',lockinfo}} = X). %% lockroot -define(IS_LOCKSCOPE(X), #xmlElement{expanded_name = {'DAV:',lockscope}} = X). %% locktoken -define(IS_LOCKTYPE(X), #xmlElement{expanded_name = {'DAV:',locktype}} = X). %% multistatus -define(IS_OWNER(X), #xmlElement{expanded_name = {'DAV:',owner}} = X). -define(IS_PROP(X), #xmlElement{expanded_name = {'DAV:',prop}} = X). -define(IS_PROPERTYUPDATE(X), #xmlElement{expanded_name = {'DAV:',propertyupdate}} = X). -define(IS_PROPFIND(X), #xmlElement{expanded_name = {'DAV:',propfind}} = X). -define(IS_PROPNAME(X), #xmlElement{expanded_name = {'DAV:',propname}} = X). %% propstat -define(IS_REMOVE(X), #xmlElement{expanded_name = {'DAV:',remove}} = X). %% response %% responsedescription -define(IS_SET(X), #xmlElement{expanded_name = {'DAV:',set}} = X). -define(IS_SHARED(X), #xmlElement{expanded_name = {'DAV:',shared}} = X). %% status %% timeout -define(IS_WRITE(X), #xmlElement{expanded_name = {'DAV:',write}} = X). -define(CONTENT(X), X#xmlElement.content). %% Parameter is always list parse_propfind([]) -> [allprop]; % RFC4918: no body then allprop, is [] no body? parse_propfind(L) -> case catch xmerl_scan:string(L, [{namespace_conformant, true}]) of {?IS_PROPFIND(X),_} -> parse_propfind(?CONTENT(X),[]); _Z -> throw(400) end. parse_propfind([?IS_PROPNAME(_H)|_T], _R) -> [propname]; parse_propfind([?IS_ALLPROP(_H)|_T], _R) -> [allprop]; parse_propfind([?IS_PROP(H)|_T], _R) when length(?CONTENT(H))==0 -> [allprop]; % NetDrive uses empty element instead of parse_propfind([?IS_PROP(H)|T], _R) -> Props = parse_prop(?CONTENT(H)), parse_propfind(T, Props); parse_propfind([_H|T], R) -> parse_propfind(T, R); parse_propfind([], R) -> R. parse_proppatch(L) -> case catch xmerl_scan:string(L, [{namespace_conformant, true}]) of {?IS_PROPERTYUPDATE(X),_} -> parse_proppatch(?CONTENT(X),[]); _Z -> throw(400) end. parse_proppatch([?IS_SET(H)|T],R) -> Props = parse_setremove(?CONTENT(H)), parse_proppatch(T,[{set,Props}|R]); parse_proppatch([?IS_REMOVE(H)|T],R) -> Props = parse_setremove(?CONTENT(H)), parse_proppatch(T,[{remove,Props}|R]); parse_proppatch([_H|T], R) -> parse_proppatch(T, R); parse_proppatch([],R) -> lists:reverse(R). % MUST proces in document order parse_setremove([?IS_PROP(X)]) -> parse_prop(?CONTENT(X)). parse_prop(L) -> parse_prop(L, []). parse_prop([H|T],L) -> case H of H when is_record(H,xmlElement) -> %% check on supported namespaces: %% - http://www.w3.org/TR/RC-xml-names#dt-prefix %% - although strict, not very forgiving towards clients %%NS = H#xmlElement.namespace, %%case NS#xmlNamespace.default of %% "" -> %% throw(400); %% _ -> ok %%end, Value = case H#xmlElement.content of [C] when is_record(C,xmlText) -> C#xmlText.value; _ -> "" end, parse_prop(T,[{H#xmlElement.expanded_name,Value}|L]); _ -> parse_prop(T,L) end; parse_prop([], L) -> L. parse_lockinfo([]) -> #lock{}; parse_lockinfo(L) -> case catch xmerl_scan:string(L, [{namespace_conformant, true}]) of {?IS_LOCKINFO(X),_} -> parse_lockinfo(?CONTENT(X),#lock{}); _Z -> throw(400) end. parse_lockinfo([?IS_LOCKSCOPE(H)|T], D) -> X = parse_lockscope(?CONTENT(H)), parse_lockinfo(T,D#lock{scope=X}); parse_lockinfo([?IS_LOCKTYPE(H)|T], D) -> X = parse_locktype(?CONTENT(H)), parse_lockinfo(T,D#lock{type=X}); parse_lockinfo([?IS_OWNER(H)|T], D) -> X = parse_owner(?CONTENT(H)), parse_lockinfo(T,D#lock{owner=X}); parse_lockinfo([_H|T],D) -> parse_lockinfo(T,D); % skip spaces and comments, etc. parse_lockinfo([], D) -> D. parse_lockscope([?IS_EXCLUSIVE(_H)|_T]) -> exclusive; parse_lockscope([?IS_SHARED(_H)|_T]) -> shared; parse_lockscope(_X) -> throw(400). parse_locktype([?IS_WRITE(_H)|_T]) -> write; parse_locktype(_) -> throw(400). parse_owner(X) -> Xml = xmerl:export_simple_content(X,xmerl_xml), lists:flatten(Xml). %% -------------------------------------------------------- %% Status output %% status(Status) -> status(Status,[],[]). status(Status,Response) -> status(Status,[],Response). status(Status,Headers,{xml,Response}) -> Xml = xml_expand(Response), status(Status,Headers,{content, "application/xml; charset=\"utf-8\"", Xml}); status(Status,Headers,Response) -> ?DEBUG(" -> ~p~n",[Status]), H = case get(compatibility) of microsoft -> [{header,{"MS-Author-Via","DAV"}}|Headers]; _ -> Headers end, [{status, Status},{header,{"DAV","1, 2, 3"}}|H] ++ [Response]. xml_expand(L) -> xml_expand(L, "utf-8"). xml_expand(L, Cset) -> Prolog = [""], %%Xml = xmerl:export_simple(L,xmerl_xml,[{prolog,Prolog}]), %% MS requires \r\n at end of every XML response case get(compatibility) of microsoft -> [Prolog,yaws_appmod_dav:export(L),"\r\n"]; _ -> [Prolog,yaws_appmod_dav:export(L)] end. %% -------------------------------------------------------- %% XML output (xmlerl_xml does not support CDATA) %% export([]) -> []; export([#xmlComment{}|T]) -> % for now I skip comments export(T); export([#xmlText{type=text, value=Text}|T]) -> [export_text(Text),export(T)]; export([#xmlText{type=cdata, value=Text}|T]) -> ["",export(T)]; export([#xmlElement{name=Name,attributes=Attrs,content=Content}|T]) -> export([{Name,Attrs,Content}|T]); export([{Name,Attrs,Content}|T]) when is_atom(Name)-> Tag = atom_to_list(Name), export([{Tag,Attrs,Content}|T]); export([{Tag,Attrs,[]}|T]) when is_list(Tag)-> ["<",Tag,export_attrs(Attrs)," />",export(T)]; export([{Tag,Attrs,Content}|T]) when is_list(Tag)-> ["<",Tag,export_attrs(Attrs),">", export_content(Content),"",export(T)]. export_content([]) -> ""; export_content([H|T]) when is_tuple(H) -> % tuples are XML records export([H|T]); export_content([H]) when is_number(H) -> integer_to_list(H); export_content([H]) when is_atom(H) -> atom_to_list(H); export_content(L) -> L. export_attrs([]) -> []; export_attrs([{Name,Value}|T]) -> [" ",export_id(Name),"=\"",export_id(Value),"\"",export_attrs(T)]; export_attrs([Attr|T]) -> [" \"",export_id(Attr),"\"",export_attrs(T)]. export_id(Id) when is_atom(Id) -> atom_to_list(Id); export_id(Id) when is_number(Id) -> integer_to_list(Id); export_id(Id) when is_list(Id) -> Id. yaws-2.0.2/src/yaws_config.erl0000664000175000017500000036460712605311412013237 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_config.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 16 Jan 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws_config). -author('klacke@bluetail.com'). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). -include_lib("kernel/include/file.hrl"). -ifndef(HAVE_BAD_WILDCARD). -define(WILDCARD_SUPPORTED, true). -else. -define(WILDCARD_SUPPORTED, false). -endif. -define(NEXTLINE, io_get_line(FD, '', [])). -export([load/1, make_default_gconf/2, make_default_sconf/0, make_default_sconf/2, add_sconf/1, add_yaws_auth/1, add_yaws_soap_srv/1, add_yaws_soap_srv/2, load_mime_types_module/2, compile_and_load_src_dir/1, search_sconf/2, search_group/2, update_sconf/3, delete_sconf/2, eq_sconfs/2, soft_setconf/4, hard_setconf/2, can_hard_gc/2, can_soft_setconf/4, can_soft_gc/2, verify_upgrade_args/2, toks/2]). %% where to look for yaws.conf paths() -> case application:get_env(yaws, config) of undefined -> case yaws:getuid() of {ok, "0"} -> %% root [yaws_generated:etcdir() ++ "/yaws/yaws.conf"]; _ -> %% developer [filename:join([yaws:home(), "yaws.conf"]), "./yaws.conf", yaws_generated:etcdir() ++ "/yaws/yaws.conf"] end; {ok, File} -> [File] end. %% load the config load(E = #env{conf = false}) -> case yaws:first(fun(F) -> yaws:exists(F) end, paths()) of false -> {error, "Can't find any config file "}; {ok, _, File} -> load(E#env{conf = {file, File}}) end; load(E) -> {file, File} = E#env.conf, error_logger:info_msg("Yaws: Using config file ~s~n", [File]), case file:open(File, [read]) of {ok, FD} -> GC = make_default_gconf(E#env.debug, E#env.id), GC1 = if E#env.traceoutput == undefined -> GC; true -> ?gc_set_tty_trace(GC, E#env.traceoutput) end, GC2 = ?gc_set_debug(GC1, E#env.debug), GC3 = GC2#gconf{trace = E#env.trace}, R = fload(FD, GC3), ?Debug("FLOAD(~s): ~p", [File, R]), case R of {ok, GC4, Cs} -> yaws:mkdir(yaws:tmpdir()), Cs1 = add_yaws_auth(Cs), add_yaws_soap_srv(GC4), validate_cs(GC4, Cs1); Err -> Err end; Err -> {error, ?F("Can't open config file ~s: ~p", [File, Err])} end. add_yaws_soap_srv(GC) when GC#gconf.enable_soap == true -> add_yaws_soap_srv(GC, true); add_yaws_soap_srv(_GC) -> []. add_yaws_soap_srv(GC, false) when GC#gconf.enable_soap == true -> [{yaws_soap_srv, {yaws_soap_srv, start_link, [GC#gconf.soap_srv_mods]}, permanent, 5000, worker, [yaws_soap_srv]}]; add_yaws_soap_srv(GC, true) when GC#gconf.enable_soap == true -> Spec = add_yaws_soap_srv(GC, false), case whereis(yaws_soap_srv) of undefined -> spawn(fun() -> supervisor:start_child(yaws_sup, hd(Spec)) end); _ -> ok end, Spec; add_yaws_soap_srv(_GC, _Start) -> []. add_yaws_auth(#sconf{}=SC) -> SC#sconf{authdirs = setup_auth(SC)}; add_yaws_auth(SCs) -> [SC#sconf{authdirs = setup_auth(SC)} || SC <- SCs]. %% We search and setup www authenticate for each directory %% specified as an auth directory or containing a .yaws_auth file. %% These are merged with server conf. setup_auth(#sconf{docroot = Docroot, xtra_docroots = XtraDocroots, authdirs = Authdirs}=SC) -> [begin Authdirs1 = load_yaws_auth_from_docroot(D, ?sc_auth_skip_docroot(SC)), Authdirs2 = load_yaws_auth_from_authdirs(Authdirs, D, []), Authdirs3 = [A || A <- Authdirs1, not lists:keymember(A#auth.dir,#auth.dir,Authdirs2)], Authdirs4 = ensure_auth_headers(Authdirs3 ++ Authdirs2), start_pam(Authdirs4), {D, Authdirs4} end || D <- [Docroot|XtraDocroots] ]. load_yaws_auth_from_docroot(_, true) -> []; load_yaws_auth_from_docroot(undefined, _) -> []; load_yaws_auth_from_docroot(Docroot, _) -> Fun = fun (Path, Acc) -> %% Strip Docroot and then filename SP = string:sub_string(Path, length(Docroot)+1), Dir = filename:dirname(SP), A = #auth{docroot=Docroot, dir=Dir}, case catch load_yaws_auth_file(Path, A) of {ok, L} -> L ++ Acc; _Other -> Acc end end, filelib:fold_files(Docroot, "^.yaws_auth$", true, Fun, []). load_yaws_auth_from_authdirs([], _, Acc) -> lists:reverse(Acc); load_yaws_auth_from_authdirs([Auth = #auth{dir=Dir}| Rest], Docroot, Acc) -> if Auth#auth.docroot /= [] andalso Auth#auth.docroot /= Docroot -> load_yaws_auth_from_authdirs(Rest, Docroot, Acc); Auth#auth.docroot == [] -> Auth1 = Auth#auth{dir=filename:nativename(Dir)}, F = fun(A) -> (A#auth.docroot == Docroot andalso A#auth.dir == Auth1#auth.dir) end, case lists:any(F, Acc) of true -> load_yaws_auth_from_authdirs(Rest, Docroot, Acc); false -> Acc1 = Acc ++ load_yaws_auth_from_authdir(Docroot, Auth1), load_yaws_auth_from_authdirs(Rest, Docroot, Acc1) end; true -> %% #auth.docroot == Docroot Auth1 = Auth#auth{docroot=Docroot, dir=filename:nativename(Dir)}, F = fun(A) -> not (A#auth.docroot == [] andalso A#auth.dir == Auth1#auth.dir) end, Acc1 = lists:filter(F, Acc), Acc2 = Acc1 ++ load_yaws_auth_from_authdir(Docroot, Auth1), load_yaws_auth_from_authdirs(Rest, Docroot, Acc2) end; load_yaws_auth_from_authdirs([{Docroot, Auths}|_], Docroot, Acc) -> load_yaws_auth_from_authdirs(Auths, Docroot, Acc); load_yaws_auth_from_authdirs([_| Rest], Docroot, Acc) -> load_yaws_auth_from_authdirs(Rest, Docroot, Acc). load_yaws_auth_from_authdir(Docroot, Auth) -> Dir = case Auth#auth.dir of "/" ++ R -> R; _ -> Auth#auth.dir end, Path = filename:join([Docroot, Dir, ".yaws_auth"]), case catch load_yaws_auth_file(Path, Auth) of {ok, Auths} -> Auths; _ -> [Auth] end. load_yaws_auth_file(Path, Auth) -> case file:consult(Path) of {ok, TermList} -> error_logger:info_msg("Reading .yaws_auth ~s~n", [Path]), parse_yaws_auth_file(TermList, Auth); {error, enoent} -> {error, enoent}; Error -> error_logger:format("Bad .yaws_auth file ~s ~p~n", [Path, Error]), Error end. ensure_auth_headers(Authdirs) -> [add_auth_headers(Auth) || Auth <- Authdirs]. add_auth_headers(Auth = #auth{headers = []}) -> %% Headers needs to be set Realm = Auth#auth.realm, Headers = yaws:make_www_authenticate_header({realm, Realm}), Auth#auth{headers = Headers}; add_auth_headers(Auth) -> Auth. start_pam([]) -> ok; start_pam([#auth{pam = false}|T]) -> start_pam(T); start_pam([A|T]) -> case whereis(yaws_pam) of undefined -> % pam not started Spec = {yaws_pam, {yaws_pam, start_link, [yaws:to_list(A#auth.pam),undefined,undefined]}, permanent, 5000, worker, [yaws_pam]}, spawn(fun() -> supervisor:start_child(yaws_sup, Spec) end); _ -> start_pam(T) end. parse_yaws_auth_file([], Auth=#auth{files=[]}) -> {ok, [Auth]}; parse_yaws_auth_file([], Auth=#auth{dir=Dir, files=Files}) -> {ok, [Auth#auth{dir=filename:join(Dir, F), files=[F]} || F <- Files]}; parse_yaws_auth_file([{realm, Realm}|T], Auth0) -> parse_yaws_auth_file(T, Auth0#auth{realm = Realm}); parse_yaws_auth_file([{pam, Pam}|T], Auth0) when is_atom(Pam) -> parse_yaws_auth_file(T, Auth0#auth{pam = Pam}); parse_yaws_auth_file([{authmod, Authmod0}|T], Auth0) when is_atom(Authmod0)-> Headers = try Authmod0:get_header() ++ Auth0#auth.headers catch _:_ -> error_logger:format("Failed to ~p:get_header() \n", [Authmod0]), Auth0#auth.headers end, parse_yaws_auth_file(T, Auth0#auth{mod = Authmod0, headers = Headers}); parse_yaws_auth_file([{file, File}|T], Auth0) -> Files = case File of "/" ++ F -> [F|Auth0#auth.files]; _ -> [File|Auth0#auth.files] end, parse_yaws_auth_file(T, Auth0#auth{files=Files}); parse_yaws_auth_file([{User, Password}|T], Auth0) when is_list(User), is_list(Password) -> Users = case lists:member({User,Password}, Auth0#auth.users) of true -> Auth0#auth.users; false -> [{User, Password} | Auth0#auth.users] end, parse_yaws_auth_file(T, Auth0#auth{users = Users}); parse_yaws_auth_file([{allow, all}|T], Auth0) -> Auth1 = case Auth0#auth.acl of none -> Auth0#auth{acl={all, [], deny_allow}}; {_,D,O} -> Auth0#auth{acl={all, D, O}} end, parse_yaws_auth_file(T, Auth1); parse_yaws_auth_file([{allow, IPs}|T], Auth0) when is_list(IPs) -> Auth1 = case Auth0#auth.acl of none -> AllowIPs = parse_auth_ips(IPs, []), Auth0#auth{acl={AllowIPs, [], deny_allow}}; {all, _, _} -> Auth0; {AllowIPs, DenyIPs, Order} -> AllowIPs2 = parse_auth_ips(IPs, []) ++ AllowIPs, Auth0#auth{acl={AllowIPs2, DenyIPs, Order}} end, parse_yaws_auth_file(T, Auth1); parse_yaws_auth_file([{deny, all}|T], Auth0) -> Auth1 = case Auth0#auth.acl of none -> Auth0#auth{acl={[], all, deny_allow}}; {A,_,O} -> Auth0#auth{acl={A, all, O}} end, parse_yaws_auth_file(T, Auth1); parse_yaws_auth_file([{deny, IPs}|T], Auth0) when is_list(IPs) -> Auth1 = case Auth0#auth.acl of none -> DenyIPs = parse_auth_ips(IPs, []), Auth0#auth{acl={[], DenyIPs, deny_allow}}; {_, all, _} -> Auth0; {AllowIPs, DenyIPs, Order} -> DenyIPs2 = parse_auth_ips(IPs, []) ++ DenyIPs, Auth0#auth{acl={AllowIPs, DenyIPs2, Order}} end, parse_yaws_auth_file(T, Auth1); parse_yaws_auth_file([{order, O}|T], Auth0) when O == allow_deny; O == deny_allow -> Auth1 = case Auth0#auth.acl of none -> Auth0#auth{acl={[], [], O}}; {A,D,_} -> Auth0#auth{acl={A, D, O}} end, parse_yaws_auth_file(T, Auth1). %% Create mime_types.erl, compile it and load it. If everything is ok, %% reload groups. %% %% If an error occured, the previously-loaded version (the first time, it's the %% static version) is kept. load_mime_types_module(GC, Groups) -> GInfo = GC#gconf.mime_types_info, SInfos = [{{SC#sconf.servername, SC#sconf.port}, SC#sconf.mime_types_info} || SC <- lists:flatten(Groups), SC#sconf.mime_types_info /= undefined], case {is_dir(yaws:id_dir(GC#gconf.id)), is_dir(yaws:tmpdir("/tmp"))} of {true, _} -> File = filename:join(yaws:id_dir(GC#gconf.id), "mime_types.erl"), load_mime_types_module(File, GInfo, SInfos); {_, true} -> File = filename:join(yaws:tmpdir("/tmp"), "mime_types.erl"), load_mime_types_module(File, GInfo, SInfos); _ -> error_logger:format("Cannot write module mime_types.erl~n" "Keep the previously-loaded version~n", []) end, lists:map(fun(Gp) -> [begin F = fun(X) when is_atom(X) -> X; (X) -> element(1, mime_types:t(SC, X)) end, TAS = SC#sconf.tilde_allowed_scripts, AS = SC#sconf.allowed_scripts, SC#sconf{tilde_allowed_scripts=lists:map(F, TAS), allowed_scripts=lists:map(F, AS)} end || SC <- Gp] end, Groups). load_mime_types_module(_, undefined, []) -> ok; load_mime_types_module(File, undefined, SInfos) -> load_mime_types_module(File, #mime_types_info{}, SInfos); load_mime_types_module(File, GInfo, SInfos) -> case mime_type_c:generate(File, GInfo, SInfos) of ok -> case compile:file(File, [binary]) of {ok, ModName, Binary} -> case code:load_binary(ModName, [], Binary) of {module, ModName} -> ok; {error, What} -> error_logger:format( "Cannot load module '~p': ~p~n" "Keep the previously-loaded version~n", [ModName, What] ) end; _ -> error_logger:format("Compilation of '~p' failed~n" "Keep the previously-loaded version~n", [File]) end; {error, Reason} -> error_logger:format("Cannot write module ~p: ~p~n" "Keep the previously-loaded version~n", [File, Reason]) end. %% Compile modules found in the configured source directories, recursively. compile_and_load_src_dir(GC) -> Incs = lists:map(fun(Dir) -> {i, Dir} end, GC#gconf.include_dir), Opts = [binary, return] ++ Incs, lists:foreach(fun(D) -> compile_and_load_src_dir([], [D], Opts) end, GC#gconf.src_dir). compile_and_load_src_dir(_Dir, [], _Opts) -> ok; compile_and_load_src_dir(Dir, [Entry0|Rest], Opts) -> Entry1 = case Dir of [] -> Entry0; _ -> filename:join(Dir, Entry0) end, case filelib:is_dir(Entry1) of true -> case file:list_dir(Entry1) of {ok, Files} -> compile_and_load_src_dir(Entry1, Files, Opts); {error, Reason} -> error_logger:format("Failed to compile modules in ~p: ~s~n", [Entry1, file:format_error(Reason)]) end; false -> case filename:extension(Entry0) of ".erl" -> compile_module_src_dir(Entry1, Opts); _ -> ok end end, compile_and_load_src_dir(Dir, Rest, Opts). compile_module_src_dir(File, Opts) -> case catch compile:file(File, Opts) of {ok, Mod, Bin} -> error_logger:format("Compiled ~p~n", [File]), load_src_dir(File, Mod, Bin); {ok, Mod, Bin, Warnings} -> WsMsg = [format_compile_warns(W,[]) || W <- Warnings], error_logger:format("Compiled ~p [~p Errors - ~p Warnings]~n~s", [File,0,length(WsMsg),WsMsg]), load_src_dir(File, Mod, Bin); {error, [], Warnings} -> WsMsg = [format_compile_warns(W,[]) || W <- Warnings], error_logger:format("Failed to compile ~p " "[~p Errors - ~p Warnings]~n~s" "*** warnings being treated as errors~n", [File,0,length(WsMsg),WsMsg]); {error, Errors, Warnings} -> WsMsg = [format_compile_warns(W,[]) || W <- Warnings], EsMsg = [format_compile_errs(E,[]) || E <- Errors], error_logger:format("Failed to compile ~p " "[~p Errors - ~p Warnings]~n~s~s", [File,length(EsMsg),length(WsMsg),EsMsg,WsMsg]); error -> error_logger:format("Failed to compile ~p~n", [File]); {'EXIT', Reason} -> error_logger:format("Failed to compile ~p: ~p~n", [File, Reason]) end. load_src_dir(File, Mod, Bin) -> case code:load_binary(Mod, File, Bin) of {module, Mod} -> ok; {error, Reason} -> error_logger:format("Cannot load module ~p: ~p~n", [Mod, Reason]) end. format_compile_warns({_, []}, Acc) -> lists:reverse(Acc); format_compile_warns({File, [{L,M,E}|Rest]}, Acc) -> Msg = io_lib:format(" ~s:~w: Warning: ~s~n", [File,L,M:format_error(E)]), format_compile_warns({File, Rest}, [Msg|Acc]). format_compile_errs({_, []}, Acc) -> lists:reverse(Acc); format_compile_errs({File, [{L,M,E}|Rest]}, Acc) -> Msg = io_lib:format(" ~s:~w: ~s~n", [File,L,M:format_error(E)]), format_compile_errs({File, Rest}, [Msg|Acc]). %% This is the function that arranges sconfs into %% different server groups validate_cs(GC, Cs) -> L = lists:map(fun(#sconf{listen=IP0}=SC0) -> SC = case is_tuple(IP0) of false -> {ok, IP} = inet_parse:address(IP0), SC0#sconf{listen=IP}; true -> SC0 end, {{SC#sconf.listen, SC#sconf.port}, SC} end, Cs), L2 = lists:map(fun(X) -> element(2, X) end, lists:keysort(1,L)), L3 = arrange(L2, start, [], []), case validate_groups(L3) of ok -> {ok, GC, L3}; Err -> Err end. validate_groups([]) -> ok; validate_groups([H|T]) -> case (catch validate_group(H)) of ok -> validate_groups(T); Err -> Err end. validate_group(List) -> [SC0|SCs] = List, %% all servers with the same IP/Port must share the same tcp configuration case lists:all(fun(SC) -> lists:keyfind(listen_opts, 1, SC#sconf.soptions) == lists:keyfind(listen_opts, 1, SC0#sconf.soptions) end, SCs) of true -> ok; false -> throw({error, ?F("Servers in the same group must share the same tcp" " configuration: ~p", [SC0#sconf.servername])}) end, %% all servers with the same IP/Port must share the same ssl configuration case lists:all(fun(SC) -> SC#sconf.ssl == SC0#sconf.ssl end, SCs) of true -> ok; false -> throw({error, ?F("Servers in the same group must share the same ssl" " configuration: ~p", [SC0#sconf.servername])}) end, %% all servernames in a group must be unique SN = lists:sort([yaws:to_lower(X#sconf.servername) || X <- List]), no_two_same(SN). no_two_same([H,H|_]) -> throw({error, ?F("Two servers in the same group cannot have same name ~p",[H])}); no_two_same([_H|T]) -> no_two_same(T); no_two_same([]) -> ok. arrange([C|Tail], start, [], B) -> arrange(Tail, {in, C}, [set_server(C)], B); arrange([], _, [], B) -> B; arrange([], _, A, B) -> [lists:reverse(A) | B]; arrange([C1|Tail], {in, C0}, A, B) -> if C1#sconf.listen == C0#sconf.listen, C1#sconf.port == C0#sconf.port -> arrange(Tail, {in, C0}, [set_server(C1)|A], B); true -> arrange(Tail, {in, C1}, [set_server(C1)], [lists:reverse(A)|B]) end. set_server(SC) -> case {SC#sconf.ssl, SC#sconf.port, ?sc_has_add_port(SC)} of {undefined, 80, _} -> SC; {undefined, Port, true} -> add_port(SC, Port); {_SSL, 443, _} -> SC; {_SSL, Port, true} -> add_port(SC, Port); {_,_,_} -> SC end. add_port(SC, Port) -> case string:tokens(SC#sconf.servername, ":") of [Srv, Prt] -> case (catch list_to_integer(Prt)) of {'EXIT', _} -> SC#sconf{servername = Srv ++ [$:|integer_to_list(Port)]}; _Int -> SC end; [Srv] -> SC#sconf{servername = Srv ++ [$:|integer_to_list(Port)]} end. make_default_gconf(Debug, Id) -> Y = yaws_dir(), Flags = case yaws_sendfile:have_sendfile() of true -> (?GC_COPY_ERRLOG bor ?GC_FAIL_ON_BIND_ERR bor ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH bor ?GC_USE_YAWS_SENDFILE); false -> (?GC_COPY_ERRLOG bor ?GC_FAIL_ON_BIND_ERR bor ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH) end, #gconf{yaws_dir = Y, ebin_dir = [filename:join([Y, "examples/ebin"])], include_dir = [filename:join([Y, "examples/include"])], trace = false, logdir = ".", cache_refresh_secs = if Debug == true -> 0; true -> 30 end, flags = if Debug -> Flags bor ?GC_DEBUG; true -> Flags end, yaws = "Yaws " ++ yaws_generated:version(), id = Id }. %% Keep this function for backward compatibility. But no one is supposed to use %% it (yaws_config is an internal module, its api is private). make_default_sconf() -> make_default_sconf([], undefined). make_default_sconf([], Port) -> make_default_sconf(filename:join([yaws_dir(), "www"]), Port); make_default_sconf(DocRoot, undefined) -> make_default_sconf(DocRoot, 8000); make_default_sconf(DocRoot, Port) -> AbsDocRoot = filename:absname(DocRoot), case is_dir(AbsDocRoot) of true -> set_server(#sconf{port=Port,listen={127,0,0,1},docroot=AbsDocRoot}); false -> throw({error, ?F("Invalid docroot: directory ~s does not exist", [AbsDocRoot])}) end. yaws_dir() -> yaws:get_app_dir(). string_to_host_and_port(String) -> HostPortRE = "^(?:\\[([^\\]]+)\\]|([^:]+)):([0-9]+)$", REOptions = [{capture, all_but_first, list}], case re:run(String, HostPortRE, REOptions) of {match, [IPv6, HostOrIPv4, Port]} -> case string:to_integer(Port) of {Integer, []} when Integer >= 0, Integer =< 65535 -> case IPv6 of "" -> {ok, HostOrIPv4, Integer}; _ -> {ok, IPv6, Integer} end; _Else -> {error, ?F("~p is not a valid port number", [Port])} end; nomatch -> {error, ?F("bad host and port specifier, expected HOST:PORT; " "use [IP]:PORT for IPv6 address", [])} end. string_to_node_mod_fun(String) -> case string:tokens(String, ":") of [Node, Mod, Fun] -> {ok, list_to_atom(Node), list_to_atom(Mod), list_to_atom(Fun)}; [Mod, Fun] -> {ok, list_to_atom(Mod), list_to_atom(Fun)}; _ -> {error, ?F("bad external module specifier, " "expected NODE:MODULE:FUNCTION or MODULE:FUNCTION", [])} end. %% two states, global, server fload(FD, GC) -> case catch fload(FD, GC, [], 1, ?NEXTLINE) of {ok, GC1, Cs} -> {ok, GC1, lists:reverse(Cs)}; Err -> Err end. fload(FD, GC, Cs, _Lno, eof) -> file:close(FD), {ok, GC, Cs}; fload(FD, GC, Cs, Lno, Chars) -> case toks(Lno, Chars) of [] -> fload(FD, GC, Cs, Lno+1, ?NEXTLINE); ["subconfig", '=', Name] -> case subconfigfiles(FD, Name, Lno) of {ok, Files} -> case fload_subconfigfiles(Files, global, GC, Cs) of {ok, GC1, Cs1} -> fload(FD, GC1, Cs1, Lno+1, ?NEXTLINE); Err -> Err end; Err -> Err end; ["subconfigdir", '=', Name] -> case subconfigdir(FD, Name, Lno) of {ok, Files} -> case fload_subconfigfiles(Files, global, GC, Cs) of {ok, GC1, Cs1} -> fload(FD, GC1, Cs1, Lno+1, ?NEXTLINE); Err -> Err end; Err -> Err end; ["trace", '=', Bstr] when GC#gconf.trace == false -> case Bstr of "traffic" -> fload(FD, GC#gconf{trace = {true, traffic}}, Cs, Lno+1, ?NEXTLINE); "http" -> fload(FD, GC#gconf{trace = {true, http}}, Cs, Lno+1, ?NEXTLINE); "false" -> fload(FD, GC#gconf{trace = false}, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect false|http|traffic at line ~w",[Lno])} end; ["trace", '=', _Bstr] -> %% don't overwrite setting from commandline fload(FD, GC, Cs, Lno+1, ?NEXTLINE); ["logdir", '=', Logdir] -> Dir = case Logdir of "+" ++ D -> D1 = filename:absname(D), %% try to make the log directory if it doesn't exist yaws:mkdir(D1), D1; _ -> filename:absname(Logdir) end, case is_dir(Dir) of true -> put(logdir, Dir), fload(FD, GC#gconf{logdir = Dir}, Cs, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect directory at line ~w (logdir ~s)", [Lno, Dir])} end; ["ebin_dir", '=', Ebindir] -> Dir = filename:absname(Ebindir), case warn_dir("ebin_dir", Dir) of true -> fload(FD, GC#gconf{ebin_dir = [Dir|GC#gconf.ebin_dir]}, Cs, Lno+1, ?NEXTLINE); false -> fload(FD, GC, Cs, Lno+1, ?NEXTLINE) end; ["src_dir", '=', Srcdir] -> Dir = filename:absname(Srcdir), case warn_dir("src_dir", Dir) of true -> fload(FD, GC#gconf{src_dir = [Dir|GC#gconf.src_dir]}, Cs, Lno+1, ?NEXTLINE); false -> fload(FD, GC, Cs, Lno+1, ?NEXTLINE) end; ["runmod", '=', Mod0] -> Mod = list_to_atom(Mod0), fload(FD, GC#gconf{runmods = [Mod|GC#gconf.runmods]}, Cs, Lno+1, ?NEXTLINE); ["enable_soap", '=', Bool] -> if (Bool == "true") -> fload(FD, GC#gconf{enable_soap = true}, Cs, Lno+1, ?NEXTLINE); true -> fload(FD, GC#gconf{enable_soap = false}, Cs, Lno+1, ?NEXTLINE) end; ["soap_srv_mods", '=' | SoapSrvMods] -> case parse_soap_srv_mods(SoapSrvMods, []) of {ok, L} -> fload(FD, GC#gconf{soap_srv_mods = L}, Cs, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["max_connections", '=', Int] -> case (catch list_to_integer(Int)) of I when is_integer(I) -> fload(FD, GC#gconf{max_connections = I}, Cs, Lno+1, ?NEXTLINE); _ when Int == "nolimit" -> fload(FD, GC, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["process_options", '=', POpts] -> case parse_process_options(POpts) of {ok, ProcList} -> fload(FD, GC#gconf{process_options=ProcList}, Cs, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["large_file_chunk_size", '=', Int] -> case (catch list_to_integer(Int)) of I when is_integer(I) -> fload(FD, GC#gconf{large_file_chunk_size = I}, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["large_file_sendfile", '=', Method] -> case set_sendfile_flags(GC, Method) of {ok, GC1} -> fload(FD, GC1, Cs, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["acceptor_pool_size", '=', Int] -> case catch list_to_integer(Int) of I when is_integer(I), I >= 0 -> fload(FD, GC#gconf{acceptor_pool_size = I}, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer >= 0 at line ~w", [Lno])} end; ["log_wrap_size", '=', Int] -> case (catch list_to_integer(Int)) of I when is_integer(I) -> fload(FD, GC#gconf{log_wrap_size = I}, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["log_resolve_hostname", '=', Bool] -> case is_bool(Bool) of {true, Val} -> fload(FD, ?gc_log_set_resolve_hostname(GC, Val), Cs, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["fail_on_bind_err", '=', Bool] -> case is_bool(Bool) of {true, Val} -> fload(FD, ?gc_set_fail_on_bind_err(GC, Val), Cs, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["include_dir", '=', Incdir] -> Dir = filename:absname(Incdir), case warn_dir("include_dir", Dir) of true -> fload(FD, GC#gconf{include_dir= [Dir|GC#gconf.include_dir]}, Cs, Lno+1, ?NEXTLINE); false -> fload(FD, GC, Cs, Lno+1, ?NEXTLINE) end; ["mnesia_dir", '=', Mnesiadir] -> Dir = filename:absname(Mnesiadir), case is_dir(Dir) of true -> put(mnesiadir, Dir), fload(FD, GC#gconf{mnesia_dir = Dir}, Cs, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect mnesia directory at line ~w", [Lno])} end; ["tmpdir", '=', _TmpDir] -> %% ignore error_logger:format( "tmpdir in yaws.conf is no longer supported - ignoring\n",[] ), fload(FD, GC, Cs, Lno+1, ?NEXTLINE); ["keepalive_timeout", '=', Val] -> %% keep this bugger for backward compat for a while case (catch list_to_integer(Val)) of I when is_integer(I) -> fload(FD, GC#gconf{keepalive_timeout = I}, Cs, Lno+1, ?NEXTLINE); _ when Val == "infinity" -> fload(FD, GC#gconf{keepalive_timeout = infinity}, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["keepalive_maxuses", '=', Int] -> case (catch list_to_integer(Int)) of I when is_integer(I) -> fload(FD, GC#gconf{keepalive_maxuses = I}, Cs, Lno+1, ?NEXTLINE); _ when Int == "nolimit" -> %% nolimit is the default fload(FD, GC, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["php_exe_path", '=' , PhpPath] -> error_logger:format( "'php_exe_path' is deprecated, use 'php_handler' instead\n", []), case is_file(PhpPath) of true -> fload(FD, GC#gconf{phpexe = PhpPath}, Cs, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect executable file at line ~w", [Lno])} end; ["read_timeout", '=', _Val] -> %% deprected, don't use error_logger:format( "read_timeout in yaws.conf is no longer supported - ignoring\n",[] ), fload(FD, GC, Cs, Lno+1, ?NEXTLINE); ["max_num_cached_files", '=', Val] -> case (catch list_to_integer(Val)) of I when is_integer(I) -> fload(FD, GC#gconf{max_num_cached_files = I}, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["max_num_cached_bytes", '=', Val] -> case (catch list_to_integer(Val)) of I when is_integer(I) -> fload(FD, GC#gconf{max_num_cached_bytes = I}, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["max_size_cached_file", '=', Val] -> case (catch list_to_integer(Val)) of I when is_integer(I) -> fload(FD, GC#gconf{max_size_cached_file = I}, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["cache_refresh_secs", '=', Val] -> case (catch list_to_integer(Val)) of I when is_integer(I), I >= 0 -> fload(FD, GC#gconf{cache_refresh_secs = I}, Cs, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect 0 or positive integer at line ~w",[Lno])} end; ["copy_error_log", '=', Bool] -> case is_bool(Bool) of {true, Val} -> fload(FD, ?gc_set_copy_errlog(GC, Val), Cs, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["auth_log", '=', Bool] -> error_logger:format( "'auth_log' global variable is deprecated and ignored." " it is now a per-server variable", []), case is_bool(Bool) of {true, _Val} -> fload(FD, GC, Cs, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["id", '=', String] when GC#gconf.id == undefined; GC#gconf.id == "default" -> fload(FD, GC#gconf{id=String}, Cs, Lno+1, ?NEXTLINE); ["id", '=', String] -> error_logger:format("Ignoring 'id = ~p' setting at line ~p~n", [String,Lno]), fload(FD, GC, Cs, Lno+1, ?NEXTLINE); ["pick_first_virthost_on_nomatch", '=', Bool] -> case is_bool(Bool) of {true, Val} -> fload(FD, ?gc_set_pick_first_virthost_on_nomatch(GC,Val), Cs, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["use_fdsrv", '=', _Bool] -> %% feature removed error_logger:format( "use_fdsrv in yaws.conf is no longer supported - ignoring\n",[] ), fload(FD, GC, Cs, Lno+1, ?NEXTLINE); ["use_old_ssl", '=', Bool] -> case is_bool(Bool) of {true, Val} -> fload(FD, ?gc_set_use_old_ssl(GC,Val), Cs, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["use_large_ssl_pool", '=', _Bool] -> %% just ignore - not relevant any longer error_logger:format( "use_large_ssl_pool in yaws.conf is no longer supported" " - ignoring\n", [] ), fload(FD, GC, Cs, Lno+1, ?NEXTLINE); ["x_forwarded_for_log_proxy_whitelist", '=' | _] -> error_logger:format( "x_forwarded_for_log_proxy_whitelist in yaws.conf is no longer" " supported - ignoring\n", [] ), fload(FD, GC, Cs, Lno+1, ?NEXTLINE); ["ysession_mod", '=', Mod_str] -> Ysession_mod = list_to_atom(Mod_str), fload(FD, GC#gconf{ysession_mod = Ysession_mod}, Cs, Lno+1, ?NEXTLINE); ["server_signature", '=', Signature] -> fload(FD, GC#gconf{yaws=Signature}, Cs, Lno+1, ?NEXTLINE); ["default_type", '=', MimeType] -> case parse_mime_types_info(default_type, MimeType, GC#gconf.mime_types_info, #mime_types_info{}) of {ok, Info} -> fload(FD, GC#gconf{mime_types_info=Info}, Cs, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["default_charset", '=', Charset] -> case parse_mime_types_info(default_charset, Charset, GC#gconf.mime_types_info, #mime_types_info{}) of {ok, Info} -> fload(FD, GC#gconf{mime_types_info=Info}, Cs, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["mime_types_file", '=', File] -> case parse_mime_types_info(mime_types_file, File, GC#gconf.mime_types_info, #mime_types_info{}) of {ok, Info} -> fload(FD, GC#gconf{mime_types_info=Info}, Cs, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["add_types", '=' | NewTypes] -> case parse_mime_types_info(add_types, NewTypes, GC#gconf.mime_types_info, #mime_types_info{}) of {ok, Info} -> fload(FD, GC#gconf{mime_types_info=Info}, Cs, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["add_charsets", '=' | NewCharsets] -> case parse_mime_types_info(add_charsets, NewCharsets, GC#gconf.mime_types_info, #mime_types_info{}) of {ok, Info} -> fload(FD, GC#gconf{mime_types_info=Info}, Cs, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["nslookup_pref", '=' | Pref] -> case parse_nslookup_pref(Pref) of {ok, Families} -> fload(FD, GC#gconf{nslookup_pref = Families}, Cs, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ['<', "server", Server, '>'] -> C = #sconf{servername = Server, listen = [], php_handler = {cgi, GC#gconf.phpexe}}, fload(FD, server, GC, C, Cs, Lno+1, ?NEXTLINE); [H|_] -> {error, ?F("Unexpected tokens ~p at line ~w", [H, Lno])}; Err -> Err end. fload(FD, server, _GC, _C, _Cs, Lno, eof) -> file:close(FD), {error, ?F("Unexpected end-of-file at line ~w", [Lno])}; fload(FD, server, GC, C, Cs, Lno, Chars) -> case fload(FD, server, GC, C, Lno, Chars) of {ok, _, _, Lno1, eof} -> {error, ?F("Unexpected end-of-file at line ~w", [Lno1])}; {ok, GC1, C1, Lno1, ['<', "/server", '>']} -> HasDocroot = case C1#sconf.docroot of undefined -> Tests = [fun() -> lists:keymember("/", #proxy_cfg.prefix, C1#sconf.revproxy) end, fun() -> lists:keymember("/", 1, C1#sconf.redirect_map) end, fun() -> lists:foldl(fun(_, true) -> true; ({"/", _}, _Acc) -> true; (_, Acc) -> Acc end, false, C1#sconf.appmods) end, fun() -> ?sc_forward_proxy(C1) end], lists:any(fun(T) -> T() end, Tests); _ -> true end, case HasDocroot of true -> case C1#sconf.listen of [] -> C2 = C1#sconf{listen = {127,0,0,1}}, fload(FD, GC1, [C2|Cs], Lno1+1, ?NEXTLINE); Ls -> Cs1 = [C1#sconf{listen=L} || L <- Ls] ++ Cs, fload(FD, GC1, Cs1, Lno1+1, ?NEXTLINE) end; false -> {error, ?F("No valid docroot configured for virthost " "'~s' (port: ~w)", [C1#sconf.servername, C1#sconf.port])} end; Err -> Err end. fload(FD, server, GC, C, Lno, eof) -> file:close(FD), {ok, GC, C, Lno, eof}; fload(FD, _, _GC, _C, Lno, eof) -> file:close(FD), {error, ?F("Unexpected end-of-file at line ~w", [Lno])}; fload(FD, server, GC, C, Lno, Chars) -> case toks(Lno, Chars) of [] -> fload(FD, server, GC, C, Lno+1, ?NEXTLINE); ["subconfig", '=', Name] -> case subconfigfiles(FD, Name, Lno) of {ok, Files} -> case fload_subconfigfiles(Files, server, GC, C) of {ok, GC1, C1} -> fload(FD, server, GC1, C1, Lno+1, ?NEXTLINE); Err -> Err end; Err -> Err end; ["subconfigdir", '=', Name] -> case subconfigdir(FD, Name, Lno) of {ok, Files} -> case fload_subconfigfiles(Files, server, GC, C) of {ok, GC1, C1} -> fload(FD, server, GC1, C1, Lno+1, ?NEXTLINE); Err -> Err end; Err -> Err end; ["server_signature", '=', Sig] -> fload(FD, server, GC, C#sconf{yaws=Sig}, Lno+1, ?NEXTLINE); ["access_log", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = ?sc_set_access_log(C, Val), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["auth_log", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = ?sc_set_auth_log(C, Val), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["logger_mod", '=', Module] -> C1 = C#sconf{logger_mod = list_to_atom(Module)}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["dir_listings", '=', StrVal] -> case StrVal of "true" -> C1 = ?sc_set_dir_listings(C, true), C2 = ?sc_set_dir_all_zip(C1, true), C3 = C2#sconf{appmods = [ {"all.zip", yaws_ls}, {"all.tgz", yaws_ls}, {"all.tbz2", yaws_ls}| C2#sconf.appmods]}, fload(FD, server, GC, C3, Lno+1, ?NEXTLINE); "true_nozip" -> C1 = ?sc_set_dir_listings(C, true), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); "false" -> C1 = ?sc_set_dir_listings(C, false), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect true|true_nozip|false at line ~w",[Lno])} end; ["deflate", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = C#sconf{deflate_options=#deflate{}}, C2 = ?sc_set_deflate(C1, Val), fload(FD, server, GC, C2, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["auth_skip_docroot",'=',Bool] -> case is_bool(Bool) of {true,Val} -> C1 = ?sc_set_auth_skip_docroot(C, Val), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["dav", '=', Bool] -> case is_bool(Bool) of {true, true} -> %% Ever since WebDAV support was moved into an appmod, %% we must no longer set the dav flag in the %% sconf. Always turn it off instead. C1 = ?sc_set_dav(C, false), Runmods = GC#gconf.runmods, GC1 = case lists:member(yaws_runmod_lock, Runmods) of false -> GC#gconf{runmods=[yaws_runmod_lock|Runmods]}; true -> GC end, DavAppmods = lists:keystore(yaws_appmod_dav, 2, C1#sconf.appmods, {"/",yaws_appmod_dav}), C2 = C1#sconf{appmods=DavAppmods}, fload(FD, server, GC1, C2, Lno+1, ?NEXTLINE); {true,false} -> C1 = ?sc_set_dav(C, false), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["port", '=', Val] -> case (catch list_to_integer(Val)) of I when is_integer(I) -> C1 = C#sconf{port = I}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["rmethod", '=', Val] -> case Val of "http" -> C1 = C#sconf{rmethod = Val}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); "https" -> C1 = C#sconf{rmethod = Val}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect http or https at line ~w", [Lno])} end; ["rhost", '=', Val] -> C1 = C#sconf{rhost = Val}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["listen", '=', IP] -> case inet_parse:address(IP) of {error, _} -> {error, ?F("Expect IP address at line ~w:", [Lno])}; {ok,Addr} -> Lstn = C#sconf.listen, C1 = if is_list(Lstn) -> case lists:member(Addr, Lstn) of false -> C#sconf{listen = [Addr|Lstn]}; true -> C end; true -> C#sconf{listen = [Addr, Lstn]} end, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE) end; ["listen_backlog", '=', Val] -> case (catch list_to_integer(Val)) of B when is_integer(B) -> C1 = update_soptions(C, listen_opts, backlog, B), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["servername", '=', Name] -> C1 = ?sc_set_add_port((C#sconf{servername = Name}),false), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["serveralias", '=' | Names] -> C1 = C#sconf{serveralias = Names ++ C#sconf.serveralias}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); [ '<', "listen_opts", '>'] -> fload(FD, listen_opts, GC, C, Lno+1, ?NEXTLINE); ["docroot", '=', Rootdir | XtraDirs] -> RootDirs = lists:map(fun(R) -> filename:absname(R) end, [Rootdir | XtraDirs]), case lists:filter(fun(R) -> not is_dir(R) end, RootDirs) of [] when C#sconf.docroot =:= undefined -> C1 = C#sconf{docroot = hd(RootDirs), xtra_docroots = tl(RootDirs)}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); [] -> XtraDocroots = RootDirs ++ C#sconf.xtra_docroots, C1 = C#sconf{xtra_docroots = XtraDocroots}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); NoDirs -> error_logger:info_msg("Warning, Skip invalid docroots" " at line ~w : ~s~n", [Lno, string:join(NoDirs, ", ")]), case lists:subtract(RootDirs, NoDirs) of [] -> fload(FD, server, GC, C, Lno+1, ?NEXTLINE); [H|T] when C#sconf.docroot =:= undefined -> C1 = C#sconf{docroot = H, xtra_docroots = T}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); Ds -> XtraDocroots = Ds ++ C#sconf.xtra_docroots, C1 = C#sconf{xtra_docroots = XtraDocroots}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE) end end; ["partial_post_size",'=',Size] -> case Size of "nolimit" -> C1 = C#sconf{partial_post_size = nolimit}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); Val -> case (catch list_to_integer(Val)) of I when is_integer(I) -> C1 = C#sconf{partial_post_size = I}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer or 'nolimit' at line ~w", [Lno])} end end; ['<', "auth", '>'] -> C1 = C#sconf{authdirs=[#auth{}|C#sconf.authdirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ['<', "redirect", '>'] -> fload(FD, server_redirect, GC, C, Lno+1, ?NEXTLINE); ['<', "deflate", '>'] -> C1 = C#sconf{deflate_options=#deflate{mime_types=[]}}, fload(FD, server_deflate, GC, C1, Lno+1, ?NEXTLINE); ["default_server_on_this_ip", '=', _Bool] -> error_logger:format( "default_server_on_this_ip in yaws.conf is no longer" " supported - ignoring\n", [] ), fload(FD, server, GC, C, Lno+1, ?NEXTLINE); [ '<', "ssl", '>'] -> ssl_start(), fload(FD, ssl, GC, C#sconf{ssl = #ssl{}}, Lno+1, ?NEXTLINE); ["appmods", '=' | AppMods] -> case parse_appmods(AppMods, []) of {ok, L} -> C1 = C#sconf{appmods = L ++ C#sconf.appmods}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["dispatchmod", '=', DispatchMod] -> C1 = C#sconf{dispatch_mod = list_to_atom(DispatchMod)}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["expires", '=' | Expires] -> case parse_expires(Expires, []) of {ok, L} -> C1 = C#sconf{expires = L ++ C#sconf.expires}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["errormod_404", '=' , Module] -> C1 = C#sconf{errormod_404 = list_to_atom(Module)}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["errormod_crash", '=', Module] -> C1 = C#sconf{errormod_crash = list_to_atom(Module)}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["errormod_401", '=' , Module] -> C1 = C#sconf{errormod_401 = list_to_atom(Module)}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["arg_rewrite_mod", '=', Module] -> C1 = C#sconf{arg_rewrite_mod = list_to_atom(Module)}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["tilde_expand", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = ?sc_set_tilde_expand(C,Val), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ['<', "opaque", '>'] -> fload(FD, opaque, GC, C, Lno+1, ?NEXTLINE); ["start_mod", '=' , Module] -> C1 = C#sconf{start_mod = list_to_atom(Module)}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ['<', "rss", '>'] -> erase(rss_id), put(rss, []), fload(FD, rss, GC, C, Lno+1, ?NEXTLINE); ["tilde_allowed_scripts", '=' | Suffixes] -> C1 = C#sconf{tilde_allowed_scripts=Suffixes}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["allowed_scripts", '=' | Suffixes] -> C1 = C#sconf{allowed_scripts=Suffixes}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["index_files", '=' | Files] -> case parse_index_files(Files) of ok -> C1 = C#sconf{index_files = Files}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["revproxy", '=' | Tail] -> case parse_revproxy(Tail) of {ok, RevProxy} -> C1 = C#sconf{revproxy = [RevProxy | C#sconf.revproxy]}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); {error, url} -> {error, ?F("Bad url at line ~p",[Lno])}; {error, syntax} -> {error, ?F("Bad revproxy syntax at line ~p",[Lno])}; Error -> Error end; ["fwdproxy", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = ?sc_set_forward_proxy(C, Val), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ['<', "extra_cgi_vars", "dir", '=', Dir, '>'] -> C1 = C#sconf{extra_cgi_vars=[{Dir, []}|C#sconf.extra_cgi_vars]}, fload(FD, extra_cgi_vars, GC, C1, Lno+1, ?NEXTLINE); ["statistics", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = ?sc_set_statistics(C, Val), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["fcgi_app_server", '=' | Val] -> HostPortSpec = case Val of [HPS] -> HPS; ['[', HSpec, ']', PSpec] -> "[" ++ HSpec ++ "]" ++ PSpec end, case string_to_host_and_port(HostPortSpec) of {ok, Host, Port} -> C1 = C#sconf{fcgi_app_server = {Host, Port}}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); {error, Reason} -> {error, ?F("Invalid fcgi_app_server ~p at line ~w: ~s", [HostPortSpec, Lno, Reason])} end; ["fcgi_trace_protocol", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = ?sc_set_fcgi_trace_protocol(C, Val), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["fcgi_log_app_error", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = ?sc_set_fcgi_log_app_error(C, Val), fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["phpfcgi", '=', HostPortSpec] -> error_logger:format( "'phpfcgi' is deprecated, use 'php_handler' instead\n", []), case string_to_host_and_port(HostPortSpec) of {ok, Host, Port} -> C1 = C#sconf{php_handler = {fcgi, {Host, Port}}}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); {error, Reason} -> {error, ?F("Invalid php fcgi server ~p at line ~w: ~s", [HostPortSpec, Lno, Reason])} end; ["php_handler", '=' | PhpMod] -> case parse_phpmod(PhpMod, GC#gconf.phpexe) of {ok, I} -> C1 = C#sconf{php_handler = I}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); {error, Reason} -> {error, ?F("Invalide php_handler configuration at line ~w: ~s", [Lno, Reason])} end; ["shaper", '=', Module] -> C1 = C#sconf{shaper = list_to_atom(Module)}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); ["default_type", '=', MimeType] -> case parse_mime_types_info(default_type, MimeType, C#sconf.mime_types_info, GC#gconf.mime_types_info) of {ok, Info} -> fload(FD, server, GC, C#sconf{mime_types_info=Info}, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["default_charset", '=', Charset] -> case parse_mime_types_info(default_charset, Charset, C#sconf.mime_types_info, GC#gconf.mime_types_info) of {ok, Info} -> fload(FD, server, GC, C#sconf{mime_types_info=Info}, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["mime_types_file", '=', File] -> case parse_mime_types_info(mime_types_file, File, C#sconf.mime_types_info, GC#gconf.mime_types_info) of {ok, Info} -> fload(FD, server, GC, C#sconf{mime_types_info=Info}, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["add_types", '=' | NewTypes] -> case parse_mime_types_info(add_types, NewTypes, C#sconf.mime_types_info, GC#gconf.mime_types_info) of {ok, Info} -> fload(FD, server, GC, C#sconf{mime_types_info=Info}, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["add_charsets", '=' | NewCharsets] -> case parse_mime_types_info(add_charsets, NewCharsets, C#sconf.mime_types_info, GC#gconf.mime_types_info) of {ok, Info} -> fload(FD, server, GC, C#sconf{mime_types_info=Info}, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ['<', "/server", '>'] -> {ok, GC, C, Lno, ['<', "/server", '>']}; [H|T] -> {error, ?F("Unexpected input ~p at line ~w", [[H|T], Lno])}; Err -> Err end; fload(FD, listen_opts, GC, C, Lno, Chars) -> case toks(Lno, Chars) of [] -> fload(FD, listen_opts, GC, C, Lno+1, ?NEXTLINE); ["buffer", '=', Int] -> case (catch list_to_integer(Int)) of B when is_integer(B) -> C1 = update_soptions(C, listen_opts, buffer, B), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["delay_send", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = update_soptions(C, listen_opts, delay_send, Val), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["linger", '=', Val] -> case (catch list_to_integer(Val)) of I when is_integer(I) -> C1 = update_soptions(C, listen_opts, linger, {true, I}), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); _ when Val == "false" -> C1 = update_soptions(C, listen_opts, linger, {false, 0}), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer|false at line ~w", [Lno])} end; ["nodelay", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = update_soptions(C, listen_opts, nodelay, Val), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["priority", '=', Int] -> case (catch list_to_integer(Int)) of P when is_integer(P) -> C1 = update_soptions(C, listen_opts, priority, P), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["sndbuf", '=', Int] -> case (catch list_to_integer(Int)) of I when is_integer(I) -> C1 = update_soptions(C, listen_opts, sndbuf, I), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["recbuf", '=', Int] -> case (catch list_to_integer(Int)) of I when is_integer(I) -> C1 = update_soptions(C, listen_opts, recbuf, I), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer at line ~w", [Lno])} end; ["send_timeout", '=', Val] -> case (catch list_to_integer(Val)) of I when is_integer(I) -> C1 = update_soptions(C, listen_opts, send_timeout, I), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); _ when Val == "infinity" -> C1 = update_soptions(C, listen_opts, send_timeout, infinity), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer|infinity at line ~w", [Lno])} end; ["send_timeout_close", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = update_soptions(C, listen_opts, send_timeout_close, Val), fload(FD, listen_opts, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ['<', "/listen_opts", '>'] -> fload(FD, server, GC, C, Lno+1, ?NEXTLINE); [H|T] -> {error, ?F("Unexpected input ~p at line ~w", [[H|T], Lno])}; Err -> Err end; fload(FD, ssl, GC, C, Lno, Chars) -> case toks(Lno, Chars) of [] -> fload(FD, ssl, GC, C, Lno+1, ?NEXTLINE); %% A bunch of ssl options ["keyfile", '=', Val] -> case is_file(Val) of true -> C1 = C#sconf{ssl = (C#sconf.ssl)#ssl{keyfile = Val}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect existing file at line ~w", [Lno])} end; ["certfile", '=', Val] -> case is_file(Val) of true -> C1 = C#sconf{ssl = (C#sconf.ssl)#ssl{certfile = Val}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect existing file at line ~w", [Lno])} end; ["cacertfile", '=', Val] -> case is_file(Val) of true -> C1 = C#sconf{ssl = (C#sconf.ssl)#ssl{cacertfile = Val}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect existing file at line ~w", [Lno])} end; ["dhfile", '=', Val] -> case is_file(Val) of true -> C1 = C#sconf{ssl = (C#sconf.ssl)#ssl{dhfile = Val}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect existing file at line ~w", [Lno])} end; ["verify", '=', Val0] -> Val = try list_to_integer(Val0) catch error:badarg -> list_to_atom(Val0) end, case lists:member(Val, [0,1,2,verify_peer,verify_none]) of true -> C1 = C#sconf{ssl = (C#sconf.ssl)#ssl{verify = Val}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer or verify_none, " "verify_peer at line ~w", [Lno])} end; ["fail_if_no_peer_cert", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = C#sconf{ssl = (C#sconf.ssl)#ssl{ fail_if_no_peer_cert = Val}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["depth", '=', Val0] -> Val = (catch list_to_integer(Val0)), case lists:member(Val, [0, 1,2,3,4,5,6,7]) of true -> C1 = C#sconf{ssl = (C#sconf.ssl)#ssl{depth = Val}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer 0..7 at line ~w", [Lno])} end; ["password", '=', Val] -> C1 = C#sconf{ssl = (C#sconf.ssl)#ssl{password = Val}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); ["ciphers", '=', Val] -> try L = str2term(Val), Ciphers = ssl:cipher_suites(), case check_ciphers(L, Ciphers) of ok -> C1 = C#sconf{ssl = (C#sconf.ssl)#ssl{ciphers = L}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); Err -> Err end catch _:_ -> {error, ?F("Bad cipherspec at line ~w", [Lno])} end; ["secure_renegotiate", '=', Bool] -> case is_bool(Bool) of {true, Val} -> C1 = C#sconf{ssl=(C#sconf.ssl)#ssl{secure_renegotiate=Val}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ["client_renegotiation", '=', Bool] -> %% below, ignore dialyzer warning: case ?SSL_CLIENT_RENEGOTIATION of true -> case is_bool(Bool) of {true, Val} -> C1 = C#sconf{ssl=(C#sconf.ssl)#ssl{client_renegotiation=Val}}, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; _ -> error_logger:info_msg("Warning, client_renegotiation SSL " "option is not supported " "at line ~w~n", [Lno]), fload(FD, ssl, GC, C, Lno+1, ?NEXTLINE) end; ["honor_cipher_order", '=', Bool] -> %% below, ignore dialyzer warning: case ?HONOR_CIPHER_ORDER of true -> case is_bool(Bool) of {true, Val} -> C2 = C#sconf{ ssl=(C#sconf.ssl)#ssl{honor_cipher_order=Val} }, fload(FD, ssl, GC, C2, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; _ -> error_logger:info_msg("Warning, honor_cipher_order SSL " "option is not supported " "at line ~w~n", [Lno]), fload(FD, ssl, GC, C, Lno+1, ?NEXTLINE) end; ["protocol_version", '=' | Vsns0] -> try Vsns = [list_to_existing_atom(V) || V <- Vsns0, not is_atom(V)], C1 = C#sconf{ ssl=(C#sconf.ssl)#ssl{protocol_version=Vsns} }, fload(FD, ssl, GC, C1, Lno+1, ?NEXTLINE) catch _:_ -> {error, ?F("Bad ssl protocol_version at line ~w", [Lno])} end; ['<', "/ssl", '>'] -> fload(FD, server, GC, C, Lno+1, ?NEXTLINE); [H|T] -> {error, ?F("Unexpected input ~p at line ~w", [[H|T], Lno])}; Err -> Err end; fload(FD, server_auth, GC, C, Lno, Chars) -> [Auth|AuthDirs] = C#sconf.authdirs, case toks(Lno, Chars) of [] -> fload(FD, server_auth, GC, C, Lno+1, ?NEXTLINE); ["docroot", '=', Docroot] -> Auth1 = Auth#auth{docroot = filename:absname(Docroot)}, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ["dir", '=', Dir] -> case file:list_dir(Dir) of {ok,_} when Dir /= "/" -> error_logger:info_msg("Warning, authdir must be set " "relative docroot ~n",[]); _ -> ok end, Dir1 = yaws_api:path_norm(Dir), Auth1 = Auth#auth{dir = [Dir1 | Auth#auth.dir]}, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ["realm", '=', Realm] -> Auth1 = Auth#auth{realm = Realm}, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ["authmod", '=', Mod] -> Mod1 = list_to_atom(Mod), code:ensure_loaded(Mod1), %% Add the auth header for the mod H = try Mod1:get_header() ++ Auth#auth.headers catch _:_ -> error_logger:format("Failed to ~p:get_header() \n", [Mod1]), Auth#auth.headers end, Auth1 = Auth#auth{mod = Mod1, headers = H}, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ["user", '=', User] -> case (catch string:tokens(User, ":")) of [Name, Passwd] -> Auth1 = Auth#auth{users = [{Name, Passwd}|Auth#auth.users]}, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Invalid user at line ~w", [Lno])} end; ["allow", '=', "all"] -> Auth1 = case Auth#auth.acl of none -> Auth#auth{acl={all, [], deny_allow}}; {_,D,O} -> Auth#auth{acl={all, D, O}} end, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ["allow", '=' | IPs] -> Auth1 = case Auth#auth.acl of none -> AllowIPs = parse_auth_ips(IPs, []), Auth#auth{acl={AllowIPs, [], deny_allow}}; {all, _, _} -> Auth; {AllowIPs, DenyIPs, Order} -> AllowIPs1 = parse_auth_ips(IPs, []) ++ AllowIPs, Auth#auth{acl={AllowIPs1, DenyIPs, Order}} end, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ["deny", '=', "all"] -> Auth1 = case Auth#auth.acl of none -> Auth#auth{acl={[], all, deny_allow}}; {A,_,O} -> Auth#auth{acl={A, all, O}} end, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ["deny", '=' | IPs] -> Auth1 = case Auth#auth.acl of none -> DenyIPs = parse_auth_ips(IPs, []), Auth#auth{acl={[], DenyIPs, deny_allow}}; {_, all, _} -> Auth; {AllowIPs, DenyIPs, Order} -> DenyIPs1 = parse_auth_ips(IPs, []) ++ DenyIPs, Auth#auth{acl={AllowIPs, DenyIPs1, Order}} end, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ["order", '=', "allow", ',', "deny"] -> Auth1 = case Auth#auth.acl of none -> Auth#auth{acl={[], [], allow_deny}}; {A,D,_} -> Auth#auth{acl={A, D, allow_deny}} end, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ["order", '=', "deny", ',', "allow"] -> Auth1 = case Auth#auth.acl of none -> Auth#auth{acl={[], [], deny_allow}}; {A,D,_} -> Auth#auth{acl={A, D, deny_allow}} end, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ["pam", "service", '=', Serv] -> Auth1 = Auth#auth{pam=Serv}, C1 = C#sconf{authdirs=[Auth1|AuthDirs]}, fload(FD, server_auth, GC, C1, Lno+1, ?NEXTLINE); ['<', "/auth", '>'] -> Pam = Auth#auth.pam, Users = Auth#auth.users, Realm = Auth#auth.realm, Auth1 = case {Pam, Users} of {false, []} -> Auth; _ -> H = Auth#auth.headers ++ yaws:make_www_authenticate_header({realm, Realm}), Auth#auth{headers = H} end, AuthDirs1 = case Auth1#auth.dir of [] -> [Auth1#auth{dir="/"}|AuthDirs]; Ds -> [Auth1#auth{dir=D} || D <- Ds] ++ AuthDirs end, C1 = C#sconf{authdirs=AuthDirs1}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); [H|T] -> {error, ?F("Unexpected input ~p at line ~w", [[H|T], Lno])}; Err -> Err end; fload(FD, server_redirect, GC, C, Lno, Chars) -> RedirMap = C#sconf.redirect_map, case toks(Lno, Chars) of [] -> fload(FD, server_redirect, GC, C, Lno+1, ?NEXTLINE); [Path, '=', '=' | Rest] -> %% "Normalize" Path Path1 = filename:join([yaws_api:path_norm(Path)]), case parse_redirect(Path1, Rest, noappend, Lno) of {error, Str} -> {error, Str}; Redir -> C1 = C#sconf{redirect_map=RedirMap ++ [Redir]}, fload(FD, server_redirect, GC, C1, Lno+1, ?NEXTLINE) end; [Path, '=' | Rest] -> %% "Normalize" Path Path1 = filename:join([yaws_api:path_norm(Path)]), case parse_redirect(Path1, Rest, append, Lno) of {error, Str} -> {error, Str}; Redir -> C1 = C#sconf{redirect_map=RedirMap ++ [Redir]}, fload(FD, server_redirect, GC, C1, Lno+1, ?NEXTLINE) end; ['<', "/redirect", '>'] -> fload(FD, server, GC, C, Lno+1, ?NEXTLINE); [H|T] -> {error, ?F("Unexpected input ~p at line ~w", [[H|T], Lno])}; Err -> Err end; fload(FD, server_deflate, GC, C, Lno, Chars) -> Deflate = C#sconf.deflate_options, case toks(Lno, Chars) of [] -> fload(FD, server_deflate, GC, C, Lno+1, ?NEXTLINE); ["min_compress_size", '=', CSize] -> case (catch list_to_integer(CSize)) of I when is_integer(I), I > 0 -> Deflate1 = Deflate#deflate{min_compress_size=I}, C1 = C#sconf{deflate_options=Deflate1}, fload(FD, server_deflate, GC, C1, Lno+1, ?NEXTLINE); _ when CSize == "nolimit" -> Deflate1 = Deflate#deflate{min_compress_size=nolimit}, C1 = C#sconf{deflate_options=Deflate1}, fload(FD, server_deflate, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer > 0 at line ~w", [Lno])} end; ["mime_types", '=' | MimeTypes] -> case parse_compressible_mime_types(MimeTypes, Deflate#deflate.mime_types) of {ok, L} -> Deflate1 = Deflate#deflate{mime_types=L}, C1 = C#sconf{deflate_options=Deflate1}, fload(FD, server_deflate, GC, C1, Lno+1, ?NEXTLINE); {error, Str} -> {error, ?F("~s at line ~w", [Str, Lno])} end; ["compression_level", '=', CLevel] -> L = try list_to_integer(CLevel) catch error:badarg -> list_to_atom(CLevel) end, if L =:= none; L =:= default; L =:= best_compression; L =:= best_speed -> Deflate1 = Deflate#deflate{compression_level=L}, C1 = C#sconf{deflate_options=Deflate1}, fload(FD, server_deflate, GC, C1, Lno+1, ?NEXTLINE); is_integer(L), L >= 0, L =< 9 -> Deflate1 = Deflate#deflate{compression_level=L}, C1 = C#sconf{deflate_options=Deflate1}, fload(FD, server_deflate, GC, C1, Lno+1, ?NEXTLINE); true -> {error, ?F("Bad compression level at line ~w", [Lno])} end; ["window_size", '=', WSize] -> case (catch list_to_integer(WSize)) of I when is_integer(I), I > 8, I < 16 -> Deflate1 = Deflate#deflate{window_size=I * -1}, C1 = C#sconf{deflate_options=Deflate1}, fload(FD, server_deflate, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer between 9..15 at line ~w", [Lno])} end; ["mem_level", '=', MLevel] -> case (catch list_to_integer(MLevel)) of I when is_integer(I), I >= 1, I =< 9 -> Deflate1 = Deflate#deflate{mem_level=I}, C1 = C#sconf{deflate_options=Deflate1}, fload(FD, server_deflate, GC, C1, Lno+1, ?NEXTLINE); _ -> {error, ?F("Expect integer between 1..9 at line ~w", [Lno])} end; ["strategy", '=', Strategy] -> if Strategy =:= "default"; Strategy =:= "filtered"; Strategy =:= "huffman_only" -> Deflate1 = Deflate#deflate{strategy=list_to_atom(Strategy)}, C1 = C#sconf{deflate_options=Deflate1}, fload(FD, server_deflate, GC, C1, Lno+1, ?NEXTLINE); true -> {error, ?F("Unknown strategy ~p at line ~w", [Strategy, Lno])} end; ["use_gzip_static", '=', Bool] -> case is_bool(Bool) of {true, Val} -> Deflate1 = Deflate#deflate{use_gzip_static=Val}, C1 = C#sconf{deflate_options=Deflate1}, fload(FD, server_deflate, GC, C1, Lno+1, ?NEXTLINE); false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; ['<', "/deflate", '>'] -> Deflate1 = case Deflate#deflate.mime_types of [] -> Deflate#deflate{ mime_types = ?DEFAULT_COMPRESSIBLE_MIME_TYPES }; _ -> Deflate end, C1 = C#sconf{deflate_options = Deflate1}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); [H|T] -> {error, ?F("Unexpected input ~p at line ~w", [[H|T], Lno])}; Err -> Err end; fload(FD, extra_cgi_vars, GC, C, Lno, Chars) -> [{Dir, Vars}|EVars] = C#sconf.extra_cgi_vars, case toks(Lno, Chars) of [] -> fload(FD, extra_cgi_vars, GC, C, Lno+1, ?NEXTLINE); [Var, '=', Val] -> C1 = C#sconf{extra_cgi_vars=[{Dir, [{Var, Val} | Vars]}|EVars]}, fload(FD, extra_cgi_vars, GC, C1, Lno+1, ?NEXTLINE); ['<', "/extra_cgi_vars", '>'] -> C1 = C#sconf{extra_cgi_vars = [EVars | C#sconf.extra_cgi_vars]}, fload(FD, server, GC, C1, Lno+1, ?NEXTLINE); [H|T] -> {error, ?F("Unexpected input ~p at line ~w", [[H|T], Lno])}; Err -> Err end; fload(FD, rss, GC, C, Lno, Chars) -> case toks(Lno, Chars) of [] -> fload(FD, rss, GC, C, Lno+1, ?NEXTLINE); ["rss_id", '=', Value] -> % mandatory !! put(rss_id, list_to_atom(Value)), fload(FD, rss, GC, C, Lno+1, ?NEXTLINE); ["rss_dir", '=', Value] -> % mandatory !! put(rss, [{db_dir, Value} | get(rss)]), fload(FD, rss, GC, C, Lno+1, ?NEXTLINE); ["rss_expire", '=', Value] -> put(rss, [{expire, Value} | get(rss)]), fload(FD, rss, GC, C, Lno+1, ?NEXTLINE); ["rss_days", '=', Value] -> put(rss, [{days, Value} | get(rss)]), fload(FD, rss, GC, C, Lno+1, ?NEXTLINE); ["rss_rm_exp", '=', Value] -> put(rss, [{rm_exp, Value} | get(rss)]), fload(FD, rss, GC, C, Lno+1, ?NEXTLINE); ["rss_max", '=', Value] -> put(rss, [{rm_max, Value} | get(rss)]), fload(FD, rss, GC, C, Lno+1, ?NEXTLINE); ['<', "/rss", '>'] -> case get(rss_id) of undefined -> {error, ?F("No rss_id specified at line ~w", [Lno])}; RSSid -> yaws_rss:open(RSSid, get(rss)), fload(FD, server, GC, C, Lno+1, ?NEXTLINE) end; [H|T] -> {error, ?F("Unexpected input ~p at line ~w", [[H|T], Lno])}; Err -> Err end; fload(FD, opaque, GC, C, Lno, Chars) -> case toks(Lno, Chars) of [] -> fload(FD, opaque, GC, C, Lno+1, ?NEXTLINE); [Key, '=', Value] -> C1 = C#sconf{opaque = [{Key,Value} | C#sconf.opaque]}, fload(FD, opaque, GC, C1, Lno+1, ?NEXTLINE); [Key, '='| Value] -> String_value = lists:flatten( lists:map( fun(Item) when is_atom(Item) -> atom_to_list(Item); (Item) -> Item end, Value)), C1 = C#sconf{opaque = [{Key, String_value} | C#sconf.opaque]}, fload(FD, opaque, GC, C1, Lno+1, ?NEXTLINE); ['<', "/opaque", '>'] -> fload(FD, server, GC, C, Lno+1, ?NEXTLINE); [H|T] -> {error, ?F("Unexpected input ~p at line ~w", [[H|T], Lno])}; Err -> Err end. is_bool("true") -> {true, true}; is_bool("false") -> {true, false}; is_bool(_) -> false. warn_dir(Type, Dir) -> case is_dir(Dir) of true -> true; false -> error_logger:format("Config Warning: Directory ~s " "for ~s doesn't exist~n", [Dir, Type]), false end. is_dir(Val) -> case file:read_file_info(Val) of {ok, FI} when FI#file_info.type == directory -> true; _ -> false end. is_file(Val) -> case file:read_file_info(Val) of {ok, FI} when FI#file_info.type == regular -> true; _ -> false end. is_wildcard(Val) -> (lists:member($*, Val) orelse lists:member($?, Val) orelse (lists:member($[, Val) andalso lists:member($], Val)) orelse (lists:member(${, Val) andalso lists:member($}, Val))). %% tokenizer toks(Lno, Chars) -> toks(Lno, Chars, free, [], []). % two accumulators toks(Lno, [$#|_T], Mode, Ack, Tack) -> toks(Lno, [], Mode, Ack, Tack); toks(Lno, [H|T], free, Ack, Tack) -> %%?Debug("Char=~p", [H]), case {is_quote(H), is_string_char([H|T]),is_special(H), yaws:is_space(H)} of {_,_, _, true} -> toks(Lno, T, free, Ack, Tack); {_,_, true, _} -> toks(Lno, T, free, [], [list_to_atom([H]) | Tack]); {_,true, _,_} -> toks(Lno, T, string, [H], Tack); {_,utf8, _,_} -> toks(Lno, tl(T), string, [H, hd(T)], Tack); {true,_, _,_} -> toks(Lno, T, quote, [], Tack); {false, false, false, false} -> {error, ?F("Unexpected character <~p / ~c> at line ~w", [H,H, Lno])} end; toks(Lno, [C|T], string, Ack, Tack) -> case {is_backquote(C), is_quote(C), is_string_char([C|T]), is_special(C), yaws:is_space(C)} of {true, _, _, _,_} -> toks(Lno, T, [backquote,string], Ack, Tack); {_, _, true, _,_} -> toks(Lno, T, string, [C|Ack], Tack); {_, _, utf8, _,_} -> toks(Lno, tl(T), string, [C, hd(T)|Ack], Tack); {_, _, _, true, _} -> toks(Lno, T, free, [], [list_to_atom([C]),lists:reverse(Ack)|Tack]); {_, true, _, _, _} -> toks(Lno, T, quote, [], [lists:reverse(Ack)|Tack]); {_, _, _, _, true} -> toks(Lno, T, free, [], [lists:reverse(Ack)|Tack]); {false, false, false, false, false} -> {error, ?F("Unexpected character <~p / ~c> at line ~w", [C, C, Lno])} end; toks(Lno, [C|T], quote, Ack, Tack) -> case {is_quote(C), is_backquote(C)} of {true, _} -> toks(Lno, T, free, [], [lists:reverse(Ack)|Tack]); {_, true} -> toks(Lno, T, [backquote,quote], [C|Ack], Tack); {false, false} -> toks(Lno, T, quote, [C|Ack], Tack) end; toks(Lno, [C|T], [backquote,Mode], Ack, Tack) -> toks(Lno, T, Mode, [C|Ack], Tack); toks(_Lno, [], string, Ack, Tack) -> lists:reverse([lists:reverse(Ack) | Tack]); toks(_Lno, [], free, _,Tack) -> lists:reverse(Tack). is_quote(34) -> true ; %% $" but emacs mode can't handle it is_quote(_) -> false. is_backquote($\\) -> true ; is_backquote(_) -> false. is_string_char([C|T]) -> if $a =< C, C =< $z -> true; $A =< C, C =< $Z -> true; $0 =< C, C =< $9 -> true; C == 195 , T /= [] -> %% FIXME check that [C, hd(T)] really is a char ?? how utf8; true -> lists:member(C, [$., $/, $:, $_, $-, $+, $~, $@, $*]) end. is_special(C) -> lists:member(C, [$=, $[, $], ${, $}, $, ,$<, $>, $,]). %% parse the argument string PLString which can either be the undefined %% atom or a proplist. Currently the only supported keys are %% fullsweep_after, min_heap_size, and min_bin_vheap_size. Any other %% key/values are ignored. parse_process_options(PLString) -> case erl_scan:string(PLString ++ ".") of {ok, PLTokens, _} -> case erl_parse:parse_term(PLTokens) of {ok, undefined} -> {ok, []}; {ok, []} -> {ok, []}; {ok, [Hd|_Tl]=PList} when is_atom(Hd); is_tuple(Hd) -> %% create new safe proplist of desired options {ok, proplists_int_copy([], PList, [fullsweep_after, min_heap_size, min_bin_vheap_size])}; _ -> {error, "Expect undefined or proplist"} end; _ -> {error, "Expect undefined or proplist"} end. %% copy proplist integer values for the given keys from the %% Src proplist to the Dest proplist. Ignored keys that are not %% found or have non-integer values. Returns the new Dest proplist. proplists_int_copy(Dest, _Src, []) -> Dest; proplists_int_copy(Dest, Src, [Key|NextKeys]) -> case proplists:get_value(Key, Src) of Val when is_integer(Val) -> proplists_int_copy([{Key, Val}|Dest], Src, NextKeys); _ -> proplists_int_copy(Dest, Src, NextKeys) end. parse_soap_srv_mods(['<', Module, ',' , Handler, ',', WsdlFile, '>' | Tail], Ack) -> case is_file(WsdlFile) of true -> S = { {list_to_atom(Module), list_to_atom(Handler)}, WsdlFile}, parse_soap_srv_mods(Tail, [S |Ack]); false -> {error, ?F("Bad wsdl file ~p", [WsdlFile])} end; parse_soap_srv_mods(['<', Module, ',' , Handler, ',', WsdlFile, ',', Prefix, '>' | Tail], Ack) -> case is_file(WsdlFile) of true -> S = { {list_to_atom(Module), list_to_atom(Handler)}, WsdlFile, Prefix}, parse_soap_srv_mods(Tail, [S |Ack]); false -> {error, ?F("Bad wsdl file ~p", [WsdlFile])} end; parse_soap_srv_mods([ SoapSrvMod | _Tail], _Ack) -> {error, ?F("Bad soap_srv_mods syntax: ~p", [SoapSrvMod])}; parse_soap_srv_mods([], Ack) -> {ok, Ack}. parse_appmods(['<', PathElem, ',' , AppMod, '>' | Tail], Ack) -> S = {PathElem , list_to_atom(AppMod)}, parse_appmods(Tail, [S |Ack]); parse_appmods(['<', PathElem, ',' , AppMod, "exclude_paths" |Tail], Ack)-> Paths = lists:takewhile(fun(X) -> X /= '>' end, Tail), Tail2 = lists:dropwhile(fun(X) -> X /= '>' end, Tail), Tail3 = tl(Tail2), S = {PathElem , list_to_atom(AppMod), lists:map( fun(Str) -> string:tokens(Str, "/") end, Paths)}, parse_appmods(Tail3, [S |Ack]); parse_appmods([AppMod | Tail], Ack) -> %% just some simpleminded test to catch syntax errors in the config case AppMod of [Char] -> case is_special(Char) of true -> {error, "Bad appmod syntax"}; false -> S = {AppMod, list_to_atom(AppMod)}, parse_appmods(Tail, [S | Ack]) end; _ -> S = {AppMod, list_to_atom(AppMod)}, parse_appmods(Tail, [S | Ack]) end; parse_appmods([], Ack) -> {ok, Ack}. parse_revproxy([Prefix, Url]) -> parse_revproxy_url(Prefix, Url); parse_revproxy([Prefix, Url, "intercept_mod", InterceptMod]) -> case parse_revproxy_url(Prefix, Url) of {ok, RP} -> {ok, RP#proxy_cfg{intercept_mod = list_to_atom(InterceptMod)}}; Error -> Error end; parse_revproxy([Prefix, Proto, '[', IPv6, ']', Rest, "intercept_mod", InterceptMod]) -> Url = Proto ++ "[" ++ IPv6 ++ "]" ++ Rest, parse_revproxy([Prefix, Url, "intercept_mod", InterceptMod]); parse_revproxy([Prefix, Proto, '[', IPv6, ']', Rest]) -> Url = Proto ++ "[" ++ IPv6 ++ "]" ++ Rest, parse_revproxy([Prefix, Url]); parse_revproxy(_Other) -> {error, syntax}. parse_revproxy_url(Prefix, Url) -> case (catch yaws_api:parse_url(Url)) of {'EXIT', _} -> {error, url}; URL when URL#url.path == "/" -> P = case lists:reverse(Prefix) of [$/|_Tail] -> Prefix; Other -> lists:reverse(Other) end, {ok, #proxy_cfg{prefix=P, url=URL}}; _URL -> {error, "Can't revproxy to a URL with a path "} end. parse_expires(['<', MimeType, ',' , Expire, '>' | Tail], Acc) -> {EType, Value} = case string:tokens(Expire, "+") of ["always"] -> {always, 0}; [Secs] -> {access, (catch list_to_integer(Secs))}; ["access", Secs] -> {access, (catch list_to_integer(Secs))}; ["modify", Secs] -> {modify, (catch list_to_integer(Secs))}; _ -> {error, "Bad expires syntax"} end, if EType =:= error -> {EType, Value}; not is_integer(Value) -> {error, "Bad expires syntax"}; true -> case parse_mime_type(MimeType) of {ok, "*", "*"} -> E = {all, EType, Value}, parse_expires(Tail, [E |Acc]); {ok, Type, "*"} -> E = {{Type, all}, EType, Value}, parse_expires(Tail, [E |Acc]); {ok, _Type, _SubType} -> E = {MimeType, EType, Value}, parse_expires(Tail, [E |Acc]); Error -> Error end end; parse_expires([], Acc)-> {ok, Acc}. parse_phpmod(['<', "cgi", ',', DefaultPhpPath, '>'], DefaultPhpPath) -> {ok, {cgi, DefaultPhpPath}}; parse_phpmod(['<', "cgi", ',', PhpPath, '>'], _) -> case is_file(PhpPath) of true -> {ok, {cgi, PhpPath}}; false -> {error, ?F("~s is not a regular file", [PhpPath])} end; parse_phpmod(['<', "fcgi", ',', HostPortSpec, '>'], _) -> case string_to_host_and_port(HostPortSpec) of {ok, Host, Port} -> {ok, {fcgi, {Host, Port}}}; {error, Reason} -> {error, Reason} end; parse_phpmod(['<', "fcgi", ',', '[', HostSpec, ']', PortSpec, '>'], _) -> case string_to_host_and_port("[" ++ HostSpec ++ "]" ++ PortSpec) of {ok, Host, Port} -> {ok, {fcgi, {Host, Port}}}; {error, Reason} -> {error, Reason} end; parse_phpmod(['<', "extern", ',', NodeModFunSpec, '>'], _) -> case string_to_node_mod_fun(NodeModFunSpec) of {ok, Node, Mod, Fun} -> {ok, {extern, {Node,Mod,Fun}}}; {ok, Mod, Fun} -> {ok, {extern, {Mod,Fun}}}; {error, Reason} -> {error, Reason} end. parse_compressible_mime_types(_, all) -> {ok, all}; parse_compressible_mime_types(["all"|_], _Acc) -> {ok, all}; parse_compressible_mime_types(["defaults"|Rest], Acc) -> parse_compressible_mime_types(Rest, ?DEFAULT_COMPRESSIBLE_MIME_TYPES++Acc); parse_compressible_mime_types([',' | Rest], Acc) -> parse_compressible_mime_types(Rest, Acc); parse_compressible_mime_types([MimeType | Rest], Acc) -> case parse_mime_type(MimeType) of {ok, "*", "*"} -> {ok, all}; {ok, Type, "*"} -> parse_compressible_mime_types(Rest, [{Type, all}|Acc]); {ok, Type, SubType} -> parse_compressible_mime_types(Rest, [{Type, SubType}|Acc]); Error -> Error end; parse_compressible_mime_types([], Acc) -> {ok, Acc}. parse_mime_type(MimeType) -> Res = re:run(MimeType, "^([-\\w\+]+|\\*)/([-\\w\+\.]+|\\*)$", [{capture, all_but_first, list}]), case Res of {match, [Type,SubType]} -> {ok, Type, SubType}; nomatch -> {error, "Invalid MimeType"} end. parse_index_files([]) -> ok; parse_index_files([Idx|Rest]) -> case Idx of [$/|_] when Rest /= [] -> {error, "Only the last index should be absolute"}; _ -> parse_index_files(Rest) end. is_valid_mime_type(MimeType) -> case re:run(MimeType, "^[-\\w\+]+/[-\\w\+\.]+$", [{capture, none}]) of match -> true; nomatch -> false end. parse_mime_types(['<', MimeType, ',' | Tail], Acc0) -> Exts = lists:takewhile(fun(X) -> X /= '>' end, Tail), [_|Tail2] = lists:dropwhile(fun(X) -> X /= '>' end, Tail), Acc1 = lists:foldl(fun(E, Acc) -> lists:keystore(E, 1, Acc, {E, MimeType}) end, Acc0, Exts), case is_valid_mime_type(MimeType) of true -> parse_mime_types(Tail2, Acc1); false -> {error, ?F("Invalid mime-type '~p'", [MimeType])} end; parse_mime_types([], Acc)-> {ok, lists:reverse(Acc)}; parse_mime_types(_, _) -> {error, "Unexpected tokens"}. parse_charsets(['<', Charset, ',' | Tail], Acc0) -> Exts = lists:takewhile(fun(X) -> X /= '>' end, Tail), [_|Tail2] = lists:dropwhile(fun(X) -> X /= '>' end, Tail), Acc1 = lists:foldl(fun(E, Acc) -> lists:keystore(E, 1, Acc, {E, Charset}) end, Acc0, Exts), parse_charsets(Tail2, Acc1); parse_charsets([], Acc)-> {ok, lists:reverse(Acc)}; parse_charsets(_, _) -> {error, "Unexpected tokens"}. parse_mime_types_info(Directive, Type, undefined, undefined) -> parse_mime_types_info(Directive, Type, #mime_types_info{}); parse_mime_types_info(Directive, Type, undefined, DefaultInfo) -> parse_mime_types_info(Directive, Type, DefaultInfo); parse_mime_types_info(Directive, Type, Info, _) -> parse_mime_types_info(Directive, Type, Info). parse_mime_types_info(default_type, Type, Info) -> case is_valid_mime_type(Type) of true -> {ok, Info#mime_types_info{default_type=Type}}; false -> {error, ?F("Invalid mime-type '~p'", [Type])} end; parse_mime_types_info(default_charset, Charset, Info) -> {ok, Info#mime_types_info{default_charset=Charset}}; parse_mime_types_info(mime_types_file, File, Info) -> {ok, Info#mime_types_info{mime_types_file=File}}; parse_mime_types_info(add_types, NewTypes, Info) -> case parse_mime_types(NewTypes, Info#mime_types_info.types) of {ok, Types} -> {ok, Info#mime_types_info{types=Types}}; Error -> Error end; parse_mime_types_info(add_charsets, NewCharsets, Info) -> case parse_charsets(NewCharsets, Info#mime_types_info.charsets) of {ok, Charsets} -> {ok, Info#mime_types_info{charsets=Charsets}}; Error -> Error end. parse_nslookup_pref(Pref) -> parse_nslookup_pref(Pref, []). parse_nslookup_pref(Empty, []) when Empty == [] orelse Empty == ['[', ']'] -> %% Get default value, if nslookup_pref = []. {ok, yaws:gconf_nslookup_pref(#gconf{})}; parse_nslookup_pref([C, Family | Rest], Result) when C == '[' orelse C == ',' -> case Family of "inet" -> case lists:member(inet, Result) of false -> parse_nslookup_pref(Rest, [inet | Result]); true -> parse_nslookup_pref(Rest, Result) end; "inet6" -> case lists:member(inet6, Result) of false -> parse_nslookup_pref(Rest, [inet6 | Result]); true -> parse_nslookup_pref(Rest, Result) end; _ -> case Result of [PreviousFamily | _] -> {error, ?F("Invalid nslookup_pref: invalid family or " "token '~s', after family '~s'", [Family, PreviousFamily])}; [] -> {error, ?F("Invalid nslookup_pref: invalid family or " "token '~s'", [Family])} end end; parse_nslookup_pref([']'], Result) -> {ok, lists:reverse(Result)}; parse_nslookup_pref([Invalid | _], []) -> {error, ?F("Invalid nslookup_pref: unexpected token '~s'", [Invalid])}; parse_nslookup_pref([Invalid | _], [Family | _]) -> {error, ?F("Invalid nslookup_pref: unexpected token '~s', " "after family '~s'", [Invalid, Family])}. parse_redirect(Path, [Code, URL], Mode, Lno) -> case catch list_to_integer(Code) of I when is_integer(I), I >= 300, I =< 399 -> try yaws_api:parse_url(URL, sloppy) of U when is_record(U, url) -> {Path, I, U, Mode} catch _:_ -> {error, ?F("Bad redirect URL ~p at line ~w", [URL, Lno])} end; I when is_integer(I), I >= 100, I =< 599 -> %% Only relative path are authorized here try yaws_api:parse_url(URL, sloppy) of #url{scheme=undefined, host=[], port=undefined, path=P} -> {Path, I, P, Mode}; #url{} -> {error, ?F("Bad redirect rule at line ~w: " " Absolute URL is forbidden here", [Lno])} catch _:_ -> {error, ?F("Bad redirect URL ~p at line ~w", [URL, Lno])} end; _ -> {error, ?F("Bad status code ~p at line ~w", [Code, Lno])} end; parse_redirect(Path, [CodeOrUrl], Mode, Lno) -> case catch list_to_integer(CodeOrUrl) of I when is_integer(I), I >= 300, I =< 399 -> {error, ?F("Bad redirect rule at line ~w: " "URL to redirect to is missing ", [Lno])}; I when is_integer(I), I >= 100, I =< 599 -> {Path, I, undefined, Mode}; I when is_integer(I) -> {error, ?F("Bad status code ~p at line ~w", [CodeOrUrl, Lno])}; _ -> try yaws_api:parse_url(CodeOrUrl, sloppy) of #url{}=U -> {Path, 302, U, Mode} catch _:_ -> {error, ?F("Bad redirect URL ~p at line ~w", [CodeOrUrl, Lno])} end end; parse_redirect(_Path, _, _Mode, Lno) -> {error, ?F("Bad redirect rule at line ~w", [Lno])}. ssl_start() -> case catch ssl:start() of ok -> ok; {error,{already_started,ssl}} -> ok; Err -> error_logger:format("Failed to start ssl: ~p~n", [Err]) end. %% search for an SC within Pairs that have the same, listen,port,ssl,severname %% Return {Pid, SC, Scs} or false %% Pairs is the pairs in yaws_server #state{} search_sconf(NewSC, Pairs) -> case lists:zf( fun({Pid, Scs = [SC|_]}) -> case same_virt_srv(NewSC, SC) of true -> case lists:keysearch(NewSC#sconf.servername, #sconf.servername, Scs) of {value, Found} -> {true, {Pid, Found, Scs}}; false -> false end; false -> false end end, Pairs) of [] -> false; [{Pid, Found, Scs}] -> {Pid, Found, Scs}; _Other -> error_logger:format("Fatal error, no two sconfs should " " ever be considered equal ..",[]), erlang:error(fatal_conf) end. %% find the group a new SC would belong to search_group(SC, Pairs) -> Fun = fun({Pid, [S|Ss]}) -> case same_virt_srv(S, SC) of true -> {true, {Pid, [S|Ss]}}; false -> false end end, lists:zf(Fun, Pairs). %% Return a new Pairs list with one SC updated update_sconf(NewSc, Pos, Pairs) -> lists:map( fun({Pid, Scs}) -> case same_virt_srv(hd(Scs), NewSc) of true -> L2 = lists:keydelete(NewSc#sconf.servername, #sconf.servername, Scs), {Pid, yaws:insert_at(NewSc, Pos, L2)}; false -> {Pid, Scs} end end, Pairs). %% return a new pairs list with SC removed delete_sconf(OldSc, Pairs) -> lists:zf( fun({Pid, Scs}) -> case same_virt_srv(hd(Scs), OldSc) of true -> L2 = lists:keydelete(OldSc#sconf.servername, #sconf.servername, Scs), {true, {Pid, L2}}; false -> {true, {Pid, Scs}} end end, Pairs). same_virt_srv(S, NewSc) when S#sconf.listen == NewSc#sconf.listen, S#sconf.port == NewSc#sconf.port, S#sconf.ssl == NewSc#sconf.ssl -> true; same_virt_srv(_,_) -> false. eq_sconfs(S1,S2) -> (S1#sconf.port == S2#sconf.port andalso S1#sconf.flags == S2#sconf.flags andalso S1#sconf.redirect_map == S2#sconf.redirect_map andalso S1#sconf.rhost == S2#sconf.rhost andalso S1#sconf.rmethod == S2#sconf.rmethod andalso S1#sconf.docroot == S2#sconf.docroot andalso S1#sconf.xtra_docroots == S2#sconf.xtra_docroots andalso S1#sconf.listen == S2#sconf.listen andalso S1#sconf.servername == S2#sconf.servername andalso S1#sconf.yaws == S2#sconf.yaws andalso S1#sconf.ssl == S2#sconf.ssl andalso S1#sconf.authdirs == S2#sconf.authdirs andalso S1#sconf.partial_post_size == S2#sconf.partial_post_size andalso S1#sconf.appmods == S2#sconf.appmods andalso S1#sconf.expires == S2#sconf.expires andalso S1#sconf.errormod_401 == S2#sconf.errormod_401 andalso S1#sconf.errormod_404 == S2#sconf.errormod_404 andalso S1#sconf.errormod_crash == S2#sconf.errormod_crash andalso S1#sconf.arg_rewrite_mod == S2#sconf.arg_rewrite_mod andalso S1#sconf.logger_mod == S2#sconf.logger_mod andalso S1#sconf.opaque == S2#sconf.opaque andalso S1#sconf.start_mod == S2#sconf.start_mod andalso S1#sconf.allowed_scripts == S2#sconf.allowed_scripts andalso S1#sconf.tilde_allowed_scripts == S2#sconf.tilde_allowed_scripts andalso S1#sconf.index_files == S2#sconf.index_files andalso S1#sconf.revproxy == S2#sconf.revproxy andalso S1#sconf.soptions == S2#sconf.soptions andalso S1#sconf.extra_cgi_vars == S2#sconf.extra_cgi_vars andalso S1#sconf.stats == S2#sconf.stats andalso S1#sconf.fcgi_app_server == S2#sconf.fcgi_app_server andalso S1#sconf.php_handler == S2#sconf.php_handler andalso S1#sconf.shaper == S2#sconf.shaper andalso S1#sconf.deflate_options == S2#sconf.deflate_options andalso S1#sconf.mime_types_info == S2#sconf.mime_types_info). %% This the version of setconf that perform a %% soft reconfig, it requires the args to be checked. soft_setconf(GC, Groups, OLDGC, OldGroups) -> if GC /= OLDGC -> yaws_trace:setup(GC), update_gconf(GC); true -> ok end, compile_and_load_src_dir(GC), Grps = load_mime_types_module(GC, Groups), Rems = remove_old_scs(lists:flatten(OldGroups), Grps), Adds = soft_setconf_scs(lists:flatten(Grps), 1, OldGroups), lists:foreach( fun({delete_sconf, SC}) -> delete_sconf(SC); ({add_sconf, N, SC}) -> add_sconf(N, SC); ({update_sconf, N, SC}) -> update_sconf(N, SC) end, Rems ++ Adds). hard_setconf(GC, Groups) -> case gen_server:call(yaws_server,{setconf, GC, Groups},infinity) of ok -> yaws_log:setup(GC, Groups), yaws_trace:setup(GC); E -> erlang:error(E) end. remove_old_scs([Sc|Scs], NewGroups) -> case find_group(Sc, NewGroups) of false -> [{delete_sconf, Sc} |remove_old_scs(Scs, NewGroups)]; {true, G} -> case find_sc(Sc, G) of false -> [{delete_sconf, Sc} | remove_old_scs(Scs, NewGroups)]; _ -> remove_old_scs(Scs, NewGroups) end end; remove_old_scs([],_) -> []. soft_setconf_scs([Sc|Scs], N, OldGroups) -> case find_group(Sc, OldGroups) of false -> [{add_sconf,N,Sc} | soft_setconf_scs(Scs, N+1, OldGroups)]; {true, G} -> case find_sc(Sc, G) of false -> [{add_sconf,N,Sc} | soft_setconf_scs(Scs,N+1,OldGroups)]; {true, _OldSc} -> [{update_sconf,N,Sc} | soft_setconf_scs(Scs,N+1,OldGroups)] end end; soft_setconf_scs([], _, _) -> []. %% checking code can_hard_gc(New, Old) -> if Old == undefined -> true; New#gconf.yaws_dir == Old#gconf.yaws_dir, New#gconf.runmods == Old#gconf.runmods, New#gconf.logdir == Old#gconf.logdir -> true; true -> false end. can_soft_setconf(NEWGC, NewGroups, OLDGC, OldGroups) -> can_soft_gc(NEWGC, OLDGC) andalso can_soft_sconf(lists:flatten(NewGroups), OldGroups). can_soft_gc(G1, G2) -> if G1#gconf.flags == G2#gconf.flags, G1#gconf.logdir == G2#gconf.logdir, G1#gconf.log_wrap_size == G2#gconf.log_wrap_size, G1#gconf.id == G2#gconf.id -> true; true -> false end. can_soft_sconf([Sc|Scs], OldGroups) -> case find_group(Sc, OldGroups) of false -> can_soft_sconf(Scs, OldGroups); {true, G} -> case find_sc(Sc, G) of false -> can_soft_sconf(Scs, OldGroups); {true, Old} when Old#sconf.start_mod /= Sc#sconf.start_mod -> false; {true, Old} -> case {proplists:get_value(listen_opts, Old#sconf.soptions), proplists:get_value(listen_opts, Sc#sconf.soptions)} of {Opts, Opts} -> can_soft_sconf(Scs, OldGroups); _ -> false end end end; can_soft_sconf([], _) -> true. find_group(SC, [G|Gs]) -> case same_virt_srv(SC, hd(G)) of true -> {true, G}; false -> find_group(SC, Gs) end; find_group(_,[]) -> false. find_sc(SC, [S|Ss]) -> if SC#sconf.servername == S#sconf.servername -> {true, S}; true -> find_sc(SC, Ss) end; find_sc(_SC,[]) -> false. verify_upgrade_args(GC, Groups0) when is_record(GC, gconf) -> SCs0 = lists:flatten(Groups0), case lists:all(fun(SC) -> is_record(SC, sconf) end, SCs0) of true -> %% Embedded code may give appmods as a list of strings, or %% appmods can be {StringPathElem,ModAtom} or %% {StringPathElem,ModAtom,ExcludePathsList} tuples. Handle %% all possible variants here. SCs1 = lists:map( fun(SC) -> SC#sconf{appmods = lists:map( fun({PE, Mod}) -> {PE, Mod}; ({PE,Mod,Ex}) -> {PE,Mod,Ex}; (AM) when is_list(AM) -> {AM,list_to_atom(AM)}; (AM) when is_atom(AM) -> {atom_to_list(AM), AM} end, SC#sconf.appmods)} end, SCs0), case catch validate_cs(GC, SCs1) of {ok, GC, Groups1} -> {GC, Groups1}; {error, Reason} -> erlang:error(Reason); _ -> erlang:error(badgroups) end; false -> erlang:error(badgroups) end. add_sconf(SC) -> add_sconf(-1, SC). add_sconf(Pos, SC) -> ok= gen_server:call(yaws_server, {add_sconf, Pos, SC}, infinity), ok = yaws_log:add_sconf(SC). update_sconf(Pos, SC) -> ok = gen_server:call(yaws_server, {update_sconf, Pos, SC}, infinity). delete_sconf(SC) -> ok = gen_server:call(yaws_server, {delete_sconf, SC}, infinity), ok = yaws_log:del_sconf(SC). update_gconf(GC) -> ok = gen_server:call(yaws_server, {update_gconf, GC}, infinity). parse_auth_ips([], Result) -> Result; parse_auth_ips([Str|Rest], Result) -> try parse_auth_ips(Rest, [yaws:parse_ipmask(Str)|Result]) catch _:_ -> parse_auth_ips(Rest, Result) end. subconfigfiles(FD, Name, Lno) -> {ok, Config} = file:pid2name(FD), ConfPath = filename:dirname(filename:absname(Config)), File = filename:absname(Name, ConfPath), case {is_file(File), is_wildcard(Name)} of {true,_} -> {ok, [File]}; {false,true} -> %% below, ignore dialyzer warning: case ?WILDCARD_SUPPORTED of true -> Names = filelib:wildcard(Name, ConfPath), Files = [filename:absname(N, ConfPath) || N <- lists:sort(Names)], {ok, lists:filter(fun filter_subconfigfile/1, Files)}; false -> {error, ?F("Unsupport wildcard at line ~w" " [support by releases >= R16A ]",[Lno])} end; {false,false} -> {error, ?F("Expect filename or wildcard at line ~w" " (subconfig: ~s)", [Lno, Name])} end. subconfigdir(FD, Name, Lno) -> {ok, Config} = file:pid2name(FD), ConfPath = filename:dirname(filename:absname(Config)), Dir = filename:absname(Name, ConfPath), case is_dir(Dir) of true -> case file:list_dir(Dir) of {ok, Names} -> Files = [filename:absname(N, Dir) || N <- lists:sort(Names)], {ok, lists:filter(fun filter_subconfigfile/1, Files)}; {error, Error} -> {error, ?F("Directory ~s is not readable: ~s", [Name, Error])} end; false -> {error, ?F("Expect directory at line ~w (subconfdir: ~s)", [Lno, Dir])} end. filter_subconfigfile(File) -> case filename:basename(File) of [$.|_] -> error_logger:info_msg("Yaws: Ignore subconfig file ~s~n", [File]), false; _ -> true end. fload_subconfigfiles([], global, GC, Cs) -> {ok, GC, Cs}; fload_subconfigfiles([File|Files], global, GC, Cs) -> error_logger:info_msg("Yaws: Using global subconfig file ~s~n", [File]), case file:open(File, [read]) of {ok, FD} -> R = (catch fload(FD, GC, Cs, 1, ?NEXTLINE)), ?Debug("FLOAD(~s): ~p", [File, R]), case R of {ok, GC1, Cs1} -> fload_subconfigfiles(Files, global, GC1, Cs1); Err -> Err end; Err -> {error, ?F("Can't open subconfig file ~s: ~p", [File,Err])} end; fload_subconfigfiles([], server, GC, C) -> {ok, GC, C}; fload_subconfigfiles([File|Files], server, GC, C) -> error_logger:info_msg("Yaws: Using server subconfig file ~s~n", [File]), case file:open(File, [read]) of {ok, FD} -> R = (catch fload(FD, server, GC, C, 1, ?NEXTLINE)), ?Debug("FLOAD(~s): ~p", [File, R]), case R of {ok, GC1, C1, _, eof} -> fload_subconfigfiles(Files, server, GC1, C1); {ok, _, _, Lno, ['<', "/server", '>']} -> {error, ?F("Unexpected closing tag in subconfgile ~s" " at line ~w ", [File, Lno])}; Err -> Err end; Err -> {error, ?F("Can't open subconfig file ~s: ~p", [File,Err])} end. str2term(Str0) -> Str=Str0++".", {ok,Tokens,_EndLine} = erl_scan:string(Str), {ok,AbsForm} = erl_parse:parse_exprs(Tokens), {value,Value,_Bs} = erl_eval:exprs(AbsForm, erl_eval:new_bindings()), Value. check_ciphers([], _) -> ok; check_ciphers([Spec|Specs], L) -> case lists:member(Spec, L) of true -> check_ciphers(Specs, L); false -> {error, ?F("Bad cipherspec ~p",[Spec])} end; check_ciphers(X,_) -> {error, ?F("Bad cipherspec ~p",[X])}. io_get_line(FD, Prompt, Acc) -> Next = io:get_line(FD, Prompt), if is_list(Next) -> case lists:reverse(Next) of [$\n, $\\ |More] -> io_get_line(FD, Prompt, Acc ++ lists:reverse(More)); _ -> Acc ++ Next end; true -> Next end. update_soptions(SC, Name, Key, Value) -> Opts0 = proplists:get_value(Name, SC#sconf.soptions), Opts1 = lists:keystore(Key, 1, Opts0, {Key, Value}), SOpts = lists:keystore(Name, 1, SC#sconf.soptions, {Name, Opts1}), SC#sconf{soptions = SOpts}. set_sendfile_flags(GC, "erlang") -> GC1 = ?gc_set_use_erlang_sendfile(GC, true), {ok, ?gc_set_use_yaws_sendfile(GC1, false)}; set_sendfile_flags(GC, "yaws") -> GC1 = ?gc_set_use_erlang_sendfile(GC, false), {ok, ?gc_set_use_yaws_sendfile(GC1, true)}; set_sendfile_flags(GC, "disable") -> GC1 = ?gc_set_use_erlang_sendfile(GC, false), {ok, ?gc_set_use_yaws_sendfile(GC1, false)}; set_sendfile_flags(_, _) -> {error, "Expect erlang|yaws|disable"}. yaws-2.0.2/src/yaws_trace.erl0000664000175000017500000004055512605311412013061 00000000000000-module(yaws_trace). -author('christopher@yakaz.com'). -behaviour(gen_server). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). %% API -export([ start_link/0, setup/1, set_tty_trace/1, get_type/1, open/0, open/1, write/2, write/3, disable_trace/1, enable_trace/2, set_filter/1, unset_filter/0, get_filter/0, %% Internal functions exported to be used in filters get_header_value/2, get_request_value/2 ]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -record(state, {tracedir, type = false, traces = dict:new(), tty_trace = false, filter}). %%==================================================================== %% API %%==================================================================== start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). setup(GC) -> gen_server:cast(?MODULE, {setup, GC}). set_tty_trace(Bool) -> gen_server:cast(?MODULE, {tty_trace, Bool}). get_type(#gconf{trace={true, Type}}) -> Type; get_type(_) -> undefined. open() -> open(self()). open(Owner) -> gen_server:cast(?MODULE, {open, Owner}). write(Tag, Data) -> write(self(), Tag, Data). write(Pid, Tag, Data) -> gen_server:cast(?MODULE, {write, Pid, Tag, Data}). disable_trace(infinity) -> {ok, GC, Groups} = yaws_server:getconf(), case GC#gconf.trace of false -> error_logger:info_msg("Trace already disabled~n", []); {true, _} -> yaws_api:setconf(GC#gconf{trace=false}, Groups), error_logger:info_msg("Trace disabled~n", []) end; disable_trace(Time) -> {ok, GC, Groups} = yaws_server:getconf(), case GC#gconf.trace of false -> error_logger:info_msg("Trace already disabled~n", []); {true, CurType} -> yaws_api:setconf(GC#gconf{trace=false}, Groups), timer:apply_after(Time, ?MODULE, enable_trace, [CurType, infinity]), error_logger:info_msg("Trace disabled for ~w milliseconds~n",[Time]) end. enable_trace(Type, infinity) when Type =:= http; Type =:= traffic -> {ok, GC, Groups} = yaws_server:getconf(), case GC#gconf.trace of {true, Type} -> error_logger:info_msg("~p trace already enabled~n", [Type]); {true, _} -> yaws_api:setconf(GC#gconf{trace={true, Type}}, Groups), error_logger:info_msg("~p trace enabled~n", [Type]); false -> yaws_api:setconf(GC#gconf{trace={true, Type}}, Groups), error_logger:info_msg("~p trace enabled~n", [Type]) end; enable_trace(Type, Time) when Type =:= http; Type =:= traffic -> {ok, GC, Groups} = yaws_server:getconf(), case GC#gconf.trace of {true, Type} -> error_logger:info_msg("~p trace already enabled~n", [Type]); {true, CurType} -> yaws_api:setconf(GC#gconf{trace={true, Type}}, Groups), timer:apply_after(Time, ?MODULE, enable_trace, [CurType, infinity]), error_logger:info_msg("~p trace enabled for ~w milliseconds~n", [Type, Time]); false -> yaws_api:setconf(GC#gconf{trace={true, Type}}, Groups), timer:apply_after(Time, ?MODULE, disable_trace, [infinity]), error_logger:info_msg("~p trace enabled for ~w milliseconds~n", [Type, Time]) end. set_filter(Filter) -> Expr = filter2expr(Filter), Fun = lists:flatten([ "fun(Ip, Req, Headers) ->\n", " try\n" " (", Expr, ")\n", " catch\n", " _:_ -> false\n" " end\n" " end." ]), Tokens = case erl_scan:string(Fun) of {ok, Toks, _} -> Toks; _ -> throw({error, {invalid_filter, scan_failed}}) end, ExprList = case erl_parse:parse_exprs(Tokens) of {ok, E} -> E; _ -> throw({error, {invalid_filter, parse_failed}}) end, try erl_eval:exprs(ExprList, []) of {value, Result, _} -> gen_server:call(?MODULE, {set_filter, Result}, infinity) catch _:_ -> throw({error, {invalid_filter, eval_failed}}) end. unset_filter() -> gen_server:call(?MODULE, unset_filter, infinity). get_filter() -> gen_server:call(?MODULE, get_filter, infinity). %%==================================================================== %% gen_server callbacks %%==================================================================== init([]) -> process_flag(trap_exit, true), {ok, #state{}}. %% ---- handle_call({set_filter, Fun}, _From, State) -> {reply, ok, State#state{filter=Fun}}; handle_call(unset_filter, _From, State) -> {reply, ok, State#state{filter=undefined}}; handle_call(get_filter, _From, State) -> {reply, State#state.filter, State}; handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. %% ---- handle_cast({setup, #gconf{trace=false}=GC}, State) -> Bool = ?gc_has_tty_trace(GC), {noreply, State#state{type=false, tty_trace=Bool, tracedir=undefined}}; handle_cast({setup, GC}, State) -> {true, Type} = GC#gconf.trace, Bool = ?gc_has_tty_trace(GC), Dir = filename:join(GC#gconf.logdir, subdir()), case file:make_dir(Dir) of ok -> error_logger:info_msg("Trace directory ~p created~n", [Dir]), {noreply, State#state{type=Type, tty_trace=Bool, tracedir=Dir}}; {error, Reason} -> error_logger:error_msg("Failed to create trace directory ~p: ~p~n", [Dir, file:format_error(Reason)]), {noreply, State#state{type=false, tty_trace=Bool}} end; handle_cast({tty_trace, Bool}, State) -> {noreply, State#state{tty_trace=Bool}}; handle_cast({open, _}, #state{type=false}=State) -> {noreply, State}; handle_cast({open, Owner}, State) -> Type = State#state.type, case dict:find(Owner, State#state.traces) of {ok, {Type, _Fd}} -> {noreply, State}; {ok, {_OtherType, OldFd}} -> file:close(OldFd), case open_trace(State#state.tracedir, filename(Type, Owner)) of {ok, NewFd} -> erlang:monitor(process, Owner), D = dict:store(Owner, {Type,NewFd}, State#state.traces), {noreply, State#state{traces=D}}; error -> D = dict:erase(Owner, State#state.traces), {noreply, State#state{traces=D}} end; error -> case open_trace(State#state.tracedir, filename(Type, Owner)) of {ok, NewFd} -> erlang:monitor(process, Owner), D = dict:store(Owner, {Type,NewFd}, State#state.traces), {noreply, State#state{traces=D}}; error -> {noreply, State} end end; handle_cast({write, _, _, _}, #state{type=false}=State) -> {noreply, State}; handle_cast({write, Pid, Tag, Data}, State) -> TTYTrace = State#state.tty_trace, case dict:find(Pid, State#state.traces) of {ok, {_Type, Fd}} -> write_trace(Pid, Fd, Tag, Data, TTYTrace); error -> ok end, {noreply, State}; handle_cast(_Msg, State) -> {noreply, State}. %% ---- handle_info({'DOWN', _MRef, _Type, Pid, _Info}, State) -> case dict:find(Pid, State#state.traces) of {ok, {_, Fd}} -> file:close(Fd), D = dict:erase(Pid, State#state.traces), {noreply, State#state{traces=D}}; error -> {noreply, State} end; handle_info(_Info, State) -> {noreply, State}. %% ---- terminate(_Reason, State) -> [file:close(Fd) || {_Owner, Fd} <- dict:to_list(State#state.traces)], ok. %% ---- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%==================================================================== %% Internal functions %%==================================================================== subdir() -> {{Y,M,D}, {HH,MM,SS}} = erlang:localtime(), lists:flatten( io_lib:format("trace_~4.10.0B~2.10.0B~2.10.0B_~2.10.0B~2.10.0B~2.10.0B", [Y,M,D,HH,MM,SS]) ). filename(Type, Owner) -> lists:concat(["trace.", pid_to_list(Owner), ".", Type]). open_trace(Dir, File) -> case file:open(filename:join([Dir, File]), [write, raw]) of {ok, Fd} -> Date = iso_8601_fmt(), Str = ["=====\n===== TRACE STARTED ", Date, "\n=====\n\n"], file:write(Fd, Str), {ok, Fd}; {error, Reason} -> error_logger:error_msg("Failed to open trace ~p: ~p~n", [File, file:format_error(Reason)]), error end. write_trace(Pid, Fd, from_server, Data, TTYTrace) -> Date = iso_8601_fmt(), Head = io_lib:format("~n[~s] ===== SRV -> CLI =====~n", [Date]), write_trace(Pid, Fd, [Head, Data], TTYTrace); write_trace(Pid, Fd, from_client, Data, TTYTrace) -> Date = iso_8601_fmt(), Head = io_lib:format("~n[~s] ===== CLI -> SRV =====~n", [Date]), write_trace(Pid, Fd, [Head, Data], TTYTrace); write_trace(Pid, Fd, _, Data, TTYTrace) -> Date = iso_8601_fmt(), Head = io_lib:format("~n[~s]~n", [Date]), write_trace(Pid, Fd, [Head, Data], TTYTrace). write_trace(Pid, Fd, Str, true) -> file:write(Fd, Str), io:format("Worker: ~p ~s~n", [Pid, flatten([Str])]); write_trace(_Pid, Fd, Str, false) -> file:write(Fd, Str). iso_8601_fmt() -> {{Year,Month,Day},{Hour,Min,Sec}} = erlang:localtime(), {_,_,MicroSec} = yaws:get_time_tuple(), io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B ~2.10.0B:~2.10.0B:~2.10.0B.~w", [Year, Month, Day, Hour, Min, Sec, (MicroSec div 1000)]). flatten(L) -> binary_to_list(iolist_to_binary(L)). %%==================================================================== filter2expr({'and', Tests}) -> L = [lists:flatten(["(", filter2expr(T), ")"]) || T <- Tests], string:join(L, " andalso "); filter2expr({'or', Tests}) -> L = [lists:flatten(["(", filter2expr(T), ")"]) || T <- Tests], string:join(L, " orelse "); filter2expr({'and', T1, T2}) -> Expr1 = lists:flatten(["(", filter2expr(T1), ")"]), Expr2 = lists:flatten(["(", filter2expr(T2), ")"]), lists:flatten([Expr1, " andalso ", Expr2]); filter2expr({'or', T1, T2}) -> Expr1 = lists:flatten(["(", filter2expr(T1), ")"]), Expr2 = lists:flatten(["(", filter2expr(T2), ")"]), lists:flatten([Expr1, " orelse ", Expr2]); filter2expr({'not', T}) -> Expr = lists:flatten(["(", filter2expr(T), ")"]), lists:flatten(["not ", Expr]); filter2expr({'equal', Elmt, Value}) -> Expr = [element_to_string(Elmt), " =:= ", value_to_string(Value)], lists:flatten(Expr); filter2expr({'startby', Elmt, Prefix}) -> Expr = ["lists:prefix(", value_to_string(Prefix), ",", element_to_string(Elmt), ")"], lists:flatten(Expr); filter2expr({'endwith', Elmt, Suffix}) -> Expr = ["lists:suffix(", value_to_string(Suffix), ",", element_to_string(Elmt), ")"], lists:flatten(Expr); filter2expr({'contain', Elmt, Part}) -> Expr = ["string:str(", element_to_string(Elmt), ",", value_to_string(Part), ") =/= 0"], lists:flatten(Expr); filter2expr({'match', Elmt, Re}) -> Expr = ["re:run(", element_to_string(Elmt), ",", value_to_string(Re), ", [{capture,none}]) =:= match"], lists:flatten(Expr); filter2expr(F) -> throw({error, {unknown_filter, F}}). value_to_string(Value) -> io_lib:format("~p", [Value]). element_to_string(ip) -> "Ip"; element_to_string({header, H}) -> lists:concat(["yaws_trace:get_header_value(", H, ", Headers)"]); element_to_string({request, R}) when R =:= method; R =:= path; R =:= version -> lists:concat(["yaws_trace:get_request_value(", R, ", Req)"]); element_to_string(E) -> throw({error, {unknown_element, E}}). get_header_value(connection, Headers) -> case yaws_api:headers_connection(Headers) of undefined -> []; Value -> Value end; get_header_value(accept, Headers) -> case yaws_api:headers_accept(Headers) of undefined -> []; Value -> Value end; get_header_value(host, Headers) -> case yaws_api:headers_host(Headers) of undefined -> []; Value -> Value end; get_header_value(if_modified_since, Headers) -> case yaws_api:headers_if_modified_since(Headers) of undefined -> []; Value -> Value end; get_header_value(if_match, Headers) -> case yaws_api:headers_if_match(Headers) of undefined -> []; Value -> Value end; get_header_value(if_none_match, Headers) -> case yaws_api:headers_if_none_match(Headers) of undefined -> []; Value -> Value end; get_header_value(if_range, Headers) -> case yaws_api:headers_if_range(Headers) of undefined -> []; Value -> Value end; get_header_value(if_unmodified_since, Headers) -> case yaws_api:headers_if_unmodified_since(Headers) of undefined -> []; Value -> Value end; get_header_value(range, Headers) -> case yaws_api:headers_range(Headers) of undefined -> []; Value -> Value end; get_header_value(referer, Headers) -> case yaws_api:headers_referer(Headers) of undefined -> []; Value -> Value end; get_header_value(user_agent, Headers) -> case yaws_api:headers_user_agent(Headers) of undefined -> []; Value -> Value end; get_header_value(accept_ranges, Headers) -> case yaws_api:headers_accept_ranges(Headers) of undefined -> []; Value -> Value end; get_header_value(cookie, Headers) -> lists:flatten(yaws_api:headers_cookie(Headers)); get_header_value(keep_alive, Headers) -> case yaws_api:headers_keep_alive(Headers) of undefined -> []; Value -> Value end; get_header_value(location, Headers) -> case yaws_api:headers_location(Headers) of undefined -> []; Value -> Value end; get_header_value(content_length, Headers) -> case yaws_api:headers_content_length(Headers) of undefined -> []; Value -> Value end; get_header_value(content_type, Headers) -> case yaws_api:headers_content_length(Headers) of undefined -> []; Value -> Value end; get_header_value(content_encoding, Headers) -> case yaws_api:headers_content_encoding(Headers) of undefined -> []; Value -> Value end; get_header_value(authorization, Headers) -> case yaws_api:headers_authorization(Headers) of undefined -> []; {undefined, undefined, Orig} -> lists:flatten(["::",Orig]); {User, Pass, Orig} -> lists:flatten([User,":",Pass,":",Orig]) end; get_header_value(transfer_encoding, Headers) -> case yaws_api:headers_transfer_encoding(Headers) of undefined -> []; Value -> Value end; get_header_value(x_forwarded_for, Headers) -> case yaws_api:headers_x_forwarded_for(Headers) of undefined -> []; Value -> Value end; get_header_value(Name, Headers) when is_atom(Name) -> Others = yaws_api:headers_other(Headers), case lists:keyfind(Name, 3, Others) of {http_header,_,_,_,Value} -> Value; false -> get_header_value(atom_to_list(Name), Headers) end; get_header_value(Name, Headers) -> Others = yaws_api:headers_other(Headers), case lists:keyfind(Name, 3, Others) of {http_header,_,_,_,Value} -> Value; false -> [] end. get_request_value(method, Req) -> yaws_api:http_request_method(Req); get_request_value(path, Req) -> case yaws_api:http_request_path(Req) of {abs_path, Path} -> Path; _ -> [] end; get_request_value(version, Req) -> case yaws_api:http_request_version(Req) of {Maj, Min} -> lists:concat(["HTTP/", Maj, ".", Min]); _ -> "HTTP/0.9" end. yaws-2.0.2/src/yaws_charset.hrl.in0000664000175000017500000000005212605311412014010 00000000000000-define(YAWS_CHARSET, @DEFAULT_CHARSET@). yaws-2.0.2/src/yaws_api.erl0000664000175000017500000030150512605311412012527 00000000000000%%---------------------------------------------------------------------- %%% File : yaws_api.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 24 Jan 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws_api). -author('klacke@hyber.org'). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_debug.hrl"). -export([parse_query/1, parse_post/1, parse_multipart_post/1, parse_multipart_post/2, parse_multipart/2, parse_multipart/3]). -export([code_to_phrase/1, ssi/2, redirect/1]). -export([setcookie/2, setcookie/3, setcookie/4, setcookie/5, setcookie/6]). -deprecated([{setcookie, 2, eventually}, {setcookie, 3, eventually}, {setcookie, 4, eventually}, {setcookie, 5, eventually}, {setcookie, 6, eventually}]). -export([set_cookie/3]). -export([pre_ssi_files/2, pre_ssi_string/1, pre_ssi_string/2, set_content_type/1, htmlize/1, htmlize_char/1, f/2, fl/1]). -export([find_cookie_val/2, secs/0, url_decode/1, url_decode_q_split/1, url_decode_with_encoding/2, url_encode/1, parse_url/1, parse_url/2, format_url/1, format_partial_url/2]). -export([is_absolute_URI/1]). -export([path_norm/1, path_norm_reverse/1, sanitize_file_name/1]). -export([get_line/1, mime_type/1, mime_type/2]). -export([stream_chunk_deliver/2, stream_chunk_deliver_blocking/2, stream_chunk_end/1]). -export([stream_process_deliver/2, stream_process_deliver_chunk/2, stream_process_deliver_final_chunk/2, stream_process_end/2]). -export([websocket_send/2, websocket_close/1, websocket_close/2]). -export([get_sslsocket/1]). -export([new_cookie_session/1, new_cookie_session/2, new_cookie_session/3, cookieval_to_opaque/1, request_url/1, print_cookie_sessions/0, replace_cookie_session/2, replace_cookie_session/3, delete_cookie_session/1]). -export([getconf/0, setconf/2, get_listen_port/1, embedded_start_conf/1, embedded_start_conf/2, embedded_start_conf/3, embedded_start_conf/4]). -export([set_status_code/1, reformat_header/1, reformat_header/2, reformat_request/1, reformat_response/1, reformat_url/1]). -export([set_trace/1, set_tty_trace/1, set_access_log/1]). -export([call_cgi/2, call_cgi/3]). -export([call_fcgi_responder/1, call_fcgi_responder/2, call_fcgi_authorizer/1, call_fcgi_authorizer/2]). -export([ehtml_expand/1, ehtml_expander/1, ehtml_apply/2, ehtml_expander_test/0]). -export([parse_set_cookie/1, parse_cookie/1, format_set_cookie/1, format_cookie/1, postvar/2, queryvar/2, getvar/2]). -export([binding/1,binding_exists/1, dir_listing/1, dir_listing/2, redirect_self/1]). -export([arg_clisock/1, arg_client_ip_port/1, arg_headers/1, arg_req/1, arg_orig_req/1, arg_clidata/1, arg_server_path/1, arg_querydata/1, arg_appmoddata/1, arg_docroot/1, arg_docroot_mount/1, arg_fullpath/1, arg_cont/1, arg_state/1, arg_pid/1, arg_opaque/1, arg_appmod_prepath/1, arg_prepath/1, arg_pathinfo/1]). -export([http_request_method/1, http_request_path/1, http_request_version/1, http_response_version/1, http_response_status/1, http_response_phrase/1, headers_connection/1, headers_accept/1, headers_host/1, headers_if_modified_since/1, headers_if_match/1, headers_if_none_match/1, headers_if_range/1, headers_if_unmodified_since/1, headers_range/1, headers_referer/1, headers_user_agent/1, headers_accept_ranges/1, headers_cookie/1, headers_keep_alive/1, headers_location/1, headers_content_length/1, headers_content_type/1, headers_content_encoding/1, headers_authorization/1, headers_transfer_encoding/1, headers_x_forwarded_for/1, headers_other/1]). -export([set_header/2, set_header/3, merge_header/2, merge_header/3, get_header/2, get_header/3, delete_header/2]). -import(lists, [flatten/1, reverse/1]). %% These are a bunch of accessor functions that are useful inside %% yaws scripts. arg_clisock(#arg{clisock = X}) -> X. arg_client_ip_port(#arg{client_ip_port = X}) -> X. arg_headers(#arg{headers = X}) -> X. arg_req(#arg{req = X}) -> X. arg_orig_req(#arg{orig_req = X}) -> X. arg_clidata(#arg{clidata = X}) -> X. arg_server_path(#arg{server_path = X}) -> X. arg_querydata(#arg{querydata = X}) -> X. arg_appmoddata(#arg{appmoddata = X}) -> X. arg_docroot(#arg{docroot = X}) -> X. arg_docroot_mount(#arg{docroot_mount = X}) -> X. arg_fullpath(#arg{fullpath = X}) -> X. arg_cont(#arg{cont = X}) -> X. arg_state(#arg{state = X}) -> X. arg_pid(#arg{pid = X}) -> X. arg_opaque(#arg{opaque = X}) -> X. arg_appmod_prepath(#arg{appmod_prepath = X}) -> X. arg_prepath(#arg{prepath = X}) -> X. arg_pathinfo(#arg{pathinfo = X}) -> X. http_request_method(#http_request{method = X}) -> X. http_request_path(#http_request{path = X}) -> X. http_request_version(#http_request{version = X}) -> X. http_response_version(#http_response{version = X}) -> X. http_response_status(#http_response{status = X}) -> X. http_response_phrase(#http_response{phrase = X}) -> X. headers_connection(#headers{connection = X}) -> X. headers_accept(#headers{accept = X}) -> X. headers_host(#headers{host = X}) -> X. headers_if_modified_since(#headers{if_modified_since = X}) -> X. headers_if_match(#headers{if_match = X}) -> X. headers_if_none_match(#headers{if_none_match = X}) -> X. headers_if_range(#headers{if_range = X}) -> X. headers_if_unmodified_since(#headers{if_unmodified_since = X}) -> X. headers_range(#headers{range = X}) -> X. headers_referer(#headers{referer = X}) -> X. headers_user_agent(#headers{user_agent = X}) -> X. headers_accept_ranges(#headers{accept_ranges = X}) -> X. headers_cookie(#headers{cookie = X}) -> X. headers_keep_alive(#headers{keep_alive = X}) -> X. headers_location(#headers{location = X}) -> X. headers_content_length(#headers{content_length = X}) -> X. headers_content_type(#headers{content_type = X}) -> X. headers_content_encoding(#headers{content_encoding = X}) -> X. headers_authorization(#headers{authorization = X}) -> X. headers_transfer_encoding(#headers{transfer_encoding = X}) -> X. headers_x_forwarded_for(#headers{x_forwarded_for = X}) -> X. headers_other(#headers{other = X}) -> X. %% parse the command line query data parse_query(Arg) -> case get(query_parse) of undefined -> Res = case Arg#arg.querydata of [] -> []; D -> parse_post_data_urlencoded(D) end, put(query_parse, Res), Res; Res -> Res end. %% parse url encoded POST data parse_post(Arg) -> case get(post_parse) of undefined -> H = Arg#arg.headers, Res = case H#headers.content_type of "application/x-www-form-urlencoded"++_ -> case Arg#arg.clidata of [] -> []; D -> parse_post_data_urlencoded(D) end; _ -> [] end, put(post_parse, Res), Res; Res -> Res end. %% %% Changed implementation of multipart form data. There is a new config %% parameter called %% %% partial_post_size %% %% which if set to an integer value %% will cause the content of the post content to be sent to the out/1 %% function in chunks of this size. %% %% It is possible to get the server to maintain a state on behalf of the %% out/1 user by returning {get_more, Cont, State}. %% %% %% yaws_api:parse_multipart_post/1 will return either: %% %% {cont, Cont, Res} where Res is new result(s) from this segment. This %% indicates that there is more data to come and the out/1 function %% should return {get_more, Cont, User_state} where User_state might %% usefully be a File Descriptor. %% %% {result, Res} if this is the last (or only) segment. %% %% or {error, Reason} if an error occurred during the parsing. %% %% Res is a list of {head, {Name, Hdrs}} | {part_body, Binary} | {body, Binary} %% %% Example usage could be: %% %% %% %% out(A) -> %% case yaws_api:parse_multipart_post(A) of %% {cont, Cont, Res} -> %% St = handle_res(A, Res), %% {get_more, Cont, St}; %% {result, Res} -> %% handle_res(A, Res), %% {html, f("
Done 
",[])}; %% {error, Reason} -> %% {html, f("An error occured: ~p", [Reason])} %% end. %% %% handle_res(A, [{head, {Name, Hdrs}}|T]) -> %% io:format("head:~p~n",[Name]), %% handle_res(A, T); %% handle_res(A, [{part_body, Data}|T]) -> %% io:format("part_body:~p~n",[Data]), %% handle_res(A, T); %% handle_res(A, [{body, Data}|T]) -> %% io:format("body:~p~n",[Data]), %% handle_res(A, T); %% handle_res(A, []) -> %% io:format("End_res~n"). %% %%
parse_multipart_post(Arg) -> parse_multipart_post(Arg, [list]). parse_multipart_post(Arg, Options) -> H = Arg#arg.headers, case H#headers.content_type of undefined -> {error, no_content_type}; "multipart/form-data"++Line -> case Arg#arg.cont of {cont, Cont} -> parse_multipart(un_partial(Arg#arg.clidata), {cont, Cont}); undefined -> LineArgs = parse_arg_line(Line), {value, {_, Boundary}} = lists:keysearch("boundary", 1, LineArgs), parse_multipart(un_partial(Arg#arg.clidata), Boundary, Options) end; _Other -> {error, no_multipart_form_data} end. un_partial({partial, Bin}) -> Bin; un_partial(Bin) -> Bin. parse_arg_line(Line) -> parse_arg_line(Line, []). parse_arg_line([],Acc) -> Acc; parse_arg_line([$ |Line], Acc) -> parse_arg_line(Line, Acc); parse_arg_line([$;|Line], Acc) -> {KV,Rest} = parse_arg_key(Line, [], []), parse_arg_line(Rest, [KV|Acc]). %% parse_arg_key([], Key, Value) -> make_parse_line_reply(Key, Value, []); parse_arg_key([$;|Line], Key, Value) -> make_parse_line_reply(Key, Value, [$;|Line]); parse_arg_key([$ |Line], Key, Value) -> parse_arg_key(Line, Key, Value); parse_arg_key([$=|Line], Key, Value) -> parse_arg_value(Line, Key, Value, false, false); parse_arg_key([C|Line], Key, Value) -> parse_arg_key(Line, [C|Key], Value). %% %% We need to deal with quotes and initial spaces here. %% parse_arg_value(String, Key, ValueAcc, InQuoteBool, InValueBool) %% parse_arg_value([], Key, Value, _, _) -> make_parse_line_reply(Key, Value, []); parse_arg_value([$\\,$"], Key, Value, _, _) -> make_parse_line_reply(Key, [$\\|Value], []); parse_arg_value([$\\,$"|Line], Key, Value, Quote, Begun) -> parse_arg_value(Line, Key, [$"|Value], Quote, Begun); parse_arg_value([$"|Line], Key, Value, false, _) -> parse_arg_value(Line, Key, Value, true, true); parse_arg_value([$"], Key, Value, true, _) -> make_parse_line_reply(Key, Value, []); parse_arg_value([$",$;|Line], Key, Value, true, _) -> make_parse_line_reply(Key, Value, [$;|Line]); parse_arg_value([$;|Line], Key, Value, false, _) -> make_parse_line_reply(Key, Value, [$;|Line]); parse_arg_value([$ |Line], Key, Value, false, true) -> make_parse_line_reply(Key, Value, Line); parse_arg_value([$ |Line], Key, Value, false, false) -> parse_arg_value(Line, Key, Value, false, false); parse_arg_value([C|Line], Key, Value, Quote, _) -> parse_arg_value(Line, Key, [C|Value], Quote, true). %% make_parse_line_reply(Key, Value, Rest) -> {{yaws:funreverse(Key, fun yaws:to_lowerchar/1), lists:reverse(Value)}, Rest}. -record(mp_parse_state, { state, boundary_ctx, boundary_len, hdr_end_ctx, old_data, data_type }). %% Stateful parser of multipart data - allows easy re-entry parse_multipart(Data, St) -> parse_multipart(Data, St, [list]). parse_multipart(Data, St, Options) -> case parse_multi(Data, St, Options) of {cont, St2, Res} -> {cont, {cont, St2}, lists:reverse(Res)}; {result, Res} -> {result, lists:reverse(Res)}; {error, Reason} -> {error, Reason} end. parse_multi(Data, #mp_parse_state{state=boundary}=ParseState, Acc) -> %% Find the beginning of the next part or the last boundary case binary:match(Data, ParseState#mp_parse_state.boundary_ctx) of {Pos, Len} -> %% If Pos != 0, ignore data preceding the boundary case Data of <<_:Pos/binary, Rest/binary>> when size(Rest) < Len+2 -> %% Not enough data to tell if it is the last boundary or not {cont, ParseState#mp_parse_state{old_data=Rest}, Acc}; <<_:Pos/binary, _:Len/binary, "\r\n", Rest/binary>> -> %% It is not the last boundary, so parse the next part NPState = ParseState#mp_parse_state{state=start_headers}, parse_multi(Rest, NPState, Acc); <<_:Pos/binary, _:Len/binary, "--\r\n", _/binary>> -> %% Match on the last boundary and ignore remaining data {result, Acc}; <<_:Pos/binary, Boundary:Len/binary, "--", Rest/binary>> when size(Rest) < 2 -> %% Partial match on the last boundary; need more data {cont, ParseState#mp_parse_state{old_data = <>}, Acc}; _ -> {error, malformed_multipart_post} end; nomatch -> %% No boundary found, request more data. Here we keep just enough %% data to match on the boundary the next time DLen = size(Data), BLen = ParseState#mp_parse_state.boundary_len, SkipLen = erlang:max(DLen - BLen, 0), KeepLen = erlang:min(BLen, DLen), <<_:SkipLen/binary, OldData:KeepLen/binary>> = Data, {cont, ParseState#mp_parse_state{old_data=OldData}, Acc} end; parse_multi(Data, #mp_parse_state{state=start_headers}=ParseState, Acc) -> parse_multi(Data, ParseState, Acc, [], []); parse_multi(Data, #mp_parse_state{state=body}=ParseState, Acc) -> %% Find the end of this part (i.e the next boundary) case binary:match(Data, ParseState#mp_parse_state.boundary_ctx) of {Pos, _Len} -> %% Extract the body and keep the boundary <> = Data, BodyData = case ParseState#mp_parse_state.data_type of list -> binary_to_list(Body); binary -> Body end, NAcc = [{body, BodyData}|Acc], NParseState = ParseState#mp_parse_state{state=boundary}, parse_multi(Rest, NParseState, NAcc); nomatch -> %% No boundary found, request more data. DLen = size(Data), BLen = ParseState#mp_parse_state.boundary_len, SkipLen = erlang:max(DLen - BLen, 0), KeepLen = erlang:min(BLen, DLen), <> = Data, NParseState = ParseState#mp_parse_state{state=body, old_data=OldData}, BodyData = case ParseState#mp_parse_state.data_type of list -> binary_to_list(PartData); binary -> PartData end, {cont, NParseState, [{part_body, BodyData}|Acc]} end; parse_multi(Data, {cont, #mp_parse_state{old_data=OldData}=ParseState}, _) -> %% Reentry point NData = <>, parse_multi(NData, ParseState, []); parse_multi(Data, Boundary, Options) -> %% Initial entry point FullBoundary = list_to_binary(["\r\n--", Boundary]), BoundaryCtx = binary:compile_pattern(FullBoundary), HdrEndCtx = binary:compile_pattern(<<"\r\n\r\n">>), DataType = lists:foldl(fun(_, list) -> list; (list, _) -> list; (binary, undefined) -> binary; (_, Acc) -> Acc end, undefined, Options), ParseState = #mp_parse_state{state = boundary, boundary_ctx = BoundaryCtx, boundary_len = size(FullBoundary), hdr_end_ctx = HdrEndCtx, data_type = DataType}, parse_multi(<<"\r\n", Data/binary>>, ParseState, []). parse_multi(Data, #mp_parse_state{state=start_headers}=ParseState, Acc, [], []) -> %% Find the end of headers for this part case binary:match(Data, ParseState#mp_parse_state.hdr_end_ctx) of {_Pos, _Len} -> %% We have all headers, we can parse it NParseState = ParseState#mp_parse_state{state=headers}, parse_multi(Data, NParseState, Acc, [], []); nomatch -> {cont, ParseState#mp_parse_state{old_data=Data}, Acc} end; parse_multi(Data, #mp_parse_state{state=headers}=ParseState, Acc, Name, Hdrs) -> case erlang:decode_packet(httph_bin, Data, [{packet_size, 16#4000}]) of {ok, http_eoh, Rest} -> %% All headers are parsed, get the body now Head = case Name of [] -> lists:reverse(Hdrs); _ -> {Name, lists:reverse(Hdrs)} end, NParseState = ParseState#mp_parse_state{state=body}, parse_multi(Rest, NParseState, [{head, Head}|Acc]); {ok, {http_header, _, Hdr, _, HdrVal}, Rest} when is_atom(Hdr) -> Header = {case Hdr of 'Content-Type' -> content_type; Else -> Else end, binary_to_list(HdrVal)}, parse_multi(Rest, ParseState, Acc, Name, [Header|Hdrs]); {ok, {http_header, _, Hdr, _, HdrVal}, Rest} -> HdrValStr = binary_to_list(HdrVal), case yaws:to_lower(binary_to_list(Hdr)) of "content-disposition" -> "form-data"++Params = HdrValStr, Parameters = parse_arg_line(Params), {_, NewName} = lists:keyfind("name", 1, Parameters), parse_multi(Rest, ParseState, Acc, NewName, Parameters++Hdrs); LowerHdr -> parse_multi(Rest, ParseState, Acc, Name, [{LowerHdr, HdrValStr}|Hdrs]) end; _ -> {error, malformed_multipart_post} end. %% parse POST data when ENCTYPE is unset or %% Content-type: application/x-www-form-urlencoded %% Bin is the content of ARG#arg.clidata %% the alternative is %% Content-type: multipart/form-data; boundary=-------------------7cd1d6371ec %% which is used for file upload parse_post_data_urlencoded(Bin) -> do_parse_spec(Bin, nokey, [], key). %% It will return a [{Key, Value}] list from the post data do_parse_spec(<<$%, Hi:8, Lo:8, Tail/binary>>, Last, Cur, State) when Hi /= $u -> Hex = yaws:hex_to_integer([Hi, Lo]), do_parse_spec(Tail, Last, [ Hex | Cur], State); do_parse_spec(<<$&, Tail/binary>>, _Last , Cur, key) -> [{lists:reverse(Cur), undefined} | do_parse_spec(Tail, nokey, [], key)]; %% cont keymode do_parse_spec(<<$&, Tail/binary>>, Last, Cur, value) -> V = {Last, lists:reverse(Cur)}, [V | do_parse_spec(Tail, nokey, [], key)]; do_parse_spec(<<$+, Tail/binary>>, Last, Cur, State) -> do_parse_spec(Tail, Last, [$\s|Cur], State); do_parse_spec(<<$=, Tail/binary>>, _Last, Cur, key) -> do_parse_spec(Tail, lists:reverse(Cur), [], value); %% change mode do_parse_spec(<<$%, $u, A:8, B:8,C:8,D:8, Tail/binary>>, Last, Cur, State) -> %% non-standard encoding for Unicode characters: %uxxxx, Hex = yaws:hex_to_integer([A,B,C,D]), do_parse_spec(Tail, Last, [ Hex | Cur], State); do_parse_spec(<>, Last, Cur, State) -> do_parse_spec(Tail, Last, [H|Cur], State); do_parse_spec(<<>>, nokey, Cur, _State) -> [{lists:reverse(Cur), undefined}]; do_parse_spec(<<>>, Last, Cur, _State) -> [{Last, lists:reverse(Cur)}]; do_parse_spec(undefined,_,_,_) -> []; do_parse_spec(QueryList, Last, Cur, State) when is_list(QueryList) -> do_parse_spec(list_to_binary(QueryList), Last, Cur, State). code_to_phrase(100) -> "Continue"; code_to_phrase(101) -> "Switching Protocols "; code_to_phrase(102) -> "Processing"; code_to_phrase(200) -> "OK"; code_to_phrase(201) -> "Created"; code_to_phrase(202) -> "Accepted"; code_to_phrase(203) -> "Non-Authoritative Information"; code_to_phrase(204) -> "No Content"; code_to_phrase(205) -> "Reset Content"; code_to_phrase(206) -> "Partial Content"; code_to_phrase(207) -> "Multi-Status"; code_to_phrase(208) -> "Already Reported"; code_to_phrase(226) -> "IM Used"; code_to_phrase(300) -> "Multiple Choices"; code_to_phrase(301) -> "Moved Permanently"; code_to_phrase(302) -> "Found"; code_to_phrase(303) -> "See Other"; code_to_phrase(304) -> "Not Modified"; code_to_phrase(305) -> "Use Proxy"; code_to_phrase(306) -> "(Unused)"; code_to_phrase(307) -> "Temporary Redirect"; code_to_phrase(308) -> "Permanent Redirect"; code_to_phrase(400) -> "Bad Request"; code_to_phrase(401) -> "Unauthorized"; code_to_phrase(402) -> "Payment Required"; code_to_phrase(403) -> "Forbidden"; code_to_phrase(404) -> "Not Found"; code_to_phrase(405) -> "Method Not Allowed"; code_to_phrase(406) -> "Not Acceptable"; code_to_phrase(407) -> "Proxy Authentication Required"; code_to_phrase(408) -> "Request Timeout"; code_to_phrase(409) -> "Conflict"; code_to_phrase(410) -> "Gone"; code_to_phrase(411) -> "Length Required"; code_to_phrase(412) -> "Precondition Failed"; code_to_phrase(413) -> "Request Entity Too Large"; code_to_phrase(414) -> "Request-URI Too Long"; code_to_phrase(415) -> "Unsupported Media Type"; code_to_phrase(416) -> "Requested Range Not Satisfiable"; code_to_phrase(417) -> "Expectation Failed"; code_to_phrase(418) -> "I'm a teapot"; code_to_phrase(420) -> "Enhance Your Calm"; code_to_phrase(422) -> "Unprocessable Entity"; code_to_phrase(423) -> "Locked"; code_to_phrase(424) -> "Failed Dependency"; code_to_phrase(425) -> "Unordered Collection"; code_to_phrase(426) -> "Upgrade Required"; code_to_phrase(428) -> "Precondition Required"; code_to_phrase(429) -> "Too Many Requests"; code_to_phrase(431) -> "Request Header Fields Too Large"; code_to_phrase(500) -> "Internal Server Error"; code_to_phrase(501) -> "Not Implemented"; code_to_phrase(502) -> "Bad Gateway"; code_to_phrase(503) -> "Service Unavailable"; code_to_phrase(504) -> "Gateway Timeout"; code_to_phrase(505) -> "HTTP Version Not Supported"; code_to_phrase(506) -> "Variant Also Negotiates"; code_to_phrase(507) -> "Insufficient Storage"; code_to_phrase(508) -> "Loop Detected"; code_to_phrase(510) -> "Not Extended"; code_to_phrase(511) -> "Network Authentication Required"; %% Below are some non-HTTP status codes from other protocol standards that %% we've seen used with HTTP in the wild, so we include them here. HTTP 1.1 %% section 6.1.1 allows for this sort of extensibility, but we recommend %% sticking with the HTTP status codes above for maximal portability and %% interoperability. %% code_to_phrase(451) -> "Requested Action Aborted"; % from FTP (RFC 959) code_to_phrase(452) -> "Insufficient Storage Space"; % from FTP (RFC 959) code_to_phrase(453) -> "Not Enough Bandwidth". % from RTSP (RFC 2326) %% %% server side include %% ssi(DocRoot, Files) -> L = lists:map(fun(F) -> case file:read_file([DocRoot ++ [$/|F]]) of {ok, Bin} -> Bin; {error, Reason} -> io_lib:format("Cannot include file ~p: ~p", [F, Reason]) end end, Files), {html, L}. %% include pre pre_ssi_files(DocRoot, Files) -> {html, L} = ssi(DocRoot, Files), pre_ssi_string(L). pre_ssi_string(Str) -> pre_ssi_string(Str, "box"). pre_ssi_string(Str, Class) -> {html, ["

\n
\n",
            htmlize_l(Str),
            "\n
\n
\n\n"]}. %% convenience f(Fmt, Args) -> io_lib:format(Fmt, Args). fl([Fmt, Arg | Tail]) -> [f(Fmt, Arg) | fl(Tail)]; fl([]) -> []. %% htmlize htmlize(Bin) when is_binary(Bin) -> list_to_binary(htmlize_l(binary_to_list(Bin))); htmlize(List) when is_list(List) -> htmlize_l(List). htmlize_char($>) -> <<">">>; htmlize_char($<) -> <<"<">>; htmlize_char($&) -> <<"&">>; htmlize_char($") -> <<""">>; htmlize_char(X) -> X. %% htmlize list (usually much more efficient than above) htmlize_l(List) -> htmlize_l(List, []). htmlize_l([], Acc) -> lists:reverse(Acc); htmlize_l([$>|Tail], Acc) -> htmlize_l(Tail, [$;,$t,$g,$&|Acc]); htmlize_l([$<|Tail], Acc) -> htmlize_l(Tail, [$;,$t,$l,$&|Acc]); htmlize_l([$&|Tail], Acc) -> htmlize_l(Tail, [$;,$p,$m,$a,$&|Acc]); htmlize_l([$"|Tail], Acc) -> htmlize_l(Tail, [$; , $t, $o, $u, $q ,$&|Acc]); htmlize_l([X|Tail], Acc) when is_integer(X) -> htmlize_l(Tail, [X|Acc]); htmlize_l([X|Tail], Acc) when is_binary(X) -> X2 = htmlize_l(binary_to_list(X)), htmlize_l(Tail, [X2|Acc]); htmlize_l([X|Tail], Ack) when is_list(X) -> X2 = htmlize_l(X), htmlize_l(Tail, [X2|Ack]). secs() -> {MS, S, _} = yaws:get_time_tuple(), (MS * 1000000) + S. cookie_option(secure) -> "; Secure"; cookie_option(http_only) -> "; HttpOnly"; cookie_option(I) -> throw({badarg, I}). cookie_option(expires, UTC) when is_tuple(UTC) -> ["; Expires=" | yaws:universal_time_as_string(UTC)]; cookie_option(max_age, Age) when is_integer(Age) -> V = if Age < 0 -> "0"; true -> integer_to_list(Age) end, ["; Max-Age=" | V]; cookie_option(path, Path) when is_list(Path), Path =/= [] -> ["; Path=" | Path]; cookie_option(domain, Domain) when is_list(Domain), Domain =/= [] -> ["; Domain=" | Domain]; cookie_option(comment, Comment) when is_list(Comment), Comment=/= [] -> ["; Comment=" | Comment]; cookie_option(I, _) -> throw({badarg, I}). %% @doc Generate a set_cookie header field tuple. %% This function is more RFC6265 compliant than setcookie/6 and %% therefore it deprecates setcookie/6 completely. set_cookie(Key, Value, Options) when is_list(Key), is_list(Value), is_list(Options) -> %% RFC6265 (4.1.1): Name=Value options must come first. {NV,SV} = lists:foldl(fun ({N,V}, {L1, L2}) -> {[cookie_option(N,V) | L1], L2}; (N, {L1, L2}) -> {L1, [cookie_option(N) | L2]} end, {[], []}, Options), {header, {set_cookie, [Key, $=, Value, "; Version=1", NV | SV]}}. setcookie(Name, Value) -> {header, {set_cookie, f("~s=~s;", [Name, Value])}}. setcookie(Name, Value, Path) -> {header, {set_cookie, f("~s=~s; path=~s", [Name, Value, Path])}}. setcookie(Name, Value, Path, Expire) -> setcookie(Name, Value, Path, Expire, [], []). setcookie(Name, Value, Path, Expire, Domain) -> setcookie(Name, Value, Path, Expire, Domain,[]). setcookie(Name, Value, Path, Expire, Domain, Secure) -> SetDomain = if Domain == [] -> ""; true -> " Domain="++Domain++";" end, SetExpire = if Expire == [] -> ""; true -> " Expires="++Expire++";" end, SetPath = if Path == [] -> "/"; true -> Path end, SetSecure = if Secure == on -> " secure;"; true -> "" end, {header, {set_cookie, f("~s=~s;~s~s~s Path=~s", [Name,Value,SetDomain,SetExpire, SetSecure, SetPath])}}. %% This function can be passed the cookie we get in the Arg#arg.headers.cookies %% to search for a specific cookie %% return [] if not found %% Str if found %% if several cookies with the same name are passed fron the browser, %% only the first match is returned find_cookie_val(Name, #arg{}=A) -> find_cookie_val(Name, (A#arg.headers)#headers.cookie); find_cookie_val(Name, Cookies) -> find_cookie_val2(yaws:to_lower(Name), Cookies). find_cookie_val2(_, []) -> []; find_cookie_val2(Name, [Cookie|Rest]) -> L = parse_cookie(Cookie), case lists:keyfind(Name, #cookie.key, L) of #cookie{value=undefined} -> []; #cookie{value=Value} -> Value; false -> find_cookie_val2(Name, Rest) end. %% url_decode(Path) -> url_decode_with_encoding(Path, file:native_name_encoding()). url_decode_with_encoding(Path, Encoding) -> {DecPath, QS} = url_decode(Path, []), DecPath1 = case Encoding of latin1 -> DecPath; utf8 -> case unicode:characters_to_list(list_to_binary(DecPath)) of UTF8DecPath when is_list(UTF8DecPath) -> UTF8DecPath; _ -> DecPath end end, case QS of [] -> lists:flatten(DecPath1); _ -> lists:flatten([DecPath1, $?, QS]) end. url_decode([], Acc) -> {lists:reverse(Acc), []}; url_decode([$?|Tail], Acc) -> %% Don't decode the query string here, that is parsed separately. {lists:reverse(Acc), Tail}; url_decode([$%, Hi, Lo | Tail], Acc) -> Hex = yaws:hex_to_integer([Hi, Lo]), url_decode(Tail, [Hex|Acc]); url_decode([H|T], Acc) when is_integer(H) -> url_decode(T, [H|Acc]); %% deep lists url_decode([H|T], Acc) when is_list(H) -> case url_decode(H, Acc) of {P1, []} -> {P2, QS} = url_decode(T, []), {[P1,P2], QS}; {P1, QS} -> {P1, QS++T} end. path_norm(Path) -> path_norm_reverse(lists:reverse(Path)). path_norm_reverse("/" ++ T) -> start_dir(0, "/", T); path_norm_reverse( T) -> start_dir(0, "", T). start_dir(N, Path, [$\\|T] ) -> start_dir(N, Path, [$/|T]); start_dir(N, Path, ".." ) -> rest_dir(N, Path, ""); start_dir(N, Path, "/" ++ T ) -> start_dir(N , Path, T); start_dir(N, Path, "./" ++ T ) -> start_dir(N , Path, T); start_dir(N, Path, ".\\" ++ T ) -> start_dir(N , Path, T); start_dir(N, Path, "../" ++ T ) -> start_dir(N + 1, Path, T); start_dir(N, Path, "..\\" ++ T ) -> start_dir(N + 1, Path, T); start_dir(N, Path, T ) -> rest_dir (N , Path, T). rest_dir (_N, Path, [] ) -> case Path of [] -> "/"; _ -> Path end; rest_dir (0, Path, [ $/ | T ] ) -> start_dir(0 , [ $/ | Path ], T); rest_dir (N, Path, [ $/ | T ] ) -> start_dir(N - 1, Path , T); rest_dir (N, Path, [ $\\ | T ] ) -> rest_dir(N, Path, [$/|T]); rest_dir (0, Path, [ H | T ] ) -> rest_dir (0 , [ H | Path ], T); rest_dir (N, Path, [ _H | T ] ) -> rest_dir (N , Path , T). %% url decode the path and return {Path, QueryPart} url_decode_q_split(Path) -> {DecPath, QS} = url_decode_q_split(Path, []), case file:native_name_encoding() of latin1 -> {DecPath, QS}; utf8 -> case unicode:characters_to_list(list_to_binary(DecPath)) of UTF8DecPath when is_list(UTF8DecPath) -> {UTF8DecPath, QS}; _ -> {DecPath, QS} end end. url_decode_q_split([$%, Hi, Lo | Tail], Ack) -> Hex = yaws:hex_to_integer([Hi, Lo]), if Hex == 0 -> exit(badurl); true -> ok end, url_decode_q_split(Tail, [Hex|Ack]); url_decode_q_split([$?|T], Ack) -> %% Don't decode the query string here, %% that is parsed separately. {path_norm_reverse(Ack), T}; url_decode_q_split([H|T], Ack) when H /= 0 -> url_decode_q_split(T, [H|Ack]); url_decode_q_split([], Ack) -> {path_norm_reverse(Ack), []}. url_encode([H|T]) when is_list(H) -> [url_encode(H) | url_encode(T)]; url_encode([H|T]) -> if H >= $a, $z >= H -> [H|url_encode(T)]; H >= $A, $Z >= H -> [H|url_encode(T)]; H >= $0, $9 >= H -> [H|url_encode(T)]; H == $_; H == $.; H == $-; H == $/; H == $: -> % FIXME: more.. [H|url_encode(T)]; true -> case yaws:integer_to_hex(H) of [X, Y] -> [$%, X, Y | url_encode(T)]; [X] -> [$%, $0, X | url_encode(T)] end end; url_encode([]) -> []. redirect(Url) -> [{redirect, Url}]. is_nb_space(X) -> lists:member(X, [$\s, $\t]). %% ret: {line, Line, Trail} | {lastline, Line, Trail} | need_more get_line(L) -> get_line(L, []). get_line("\r\n\r\n" ++ Tail, Cur) -> {lastline, lists:reverse(Cur), Tail}; get_line("\r\n" ++ Tail, Cur) when Tail /= [] -> case is_nb_space(hd(Tail)) of true -> %% multiline ... continue get_line(Tail, [$\n, $\r | Cur]); false -> {line, lists:reverse(Cur), Tail} end; get_line("\r\n", Cur) -> {line, lists:reverse(Cur), []}; get_line([H|T], Cur) -> get_line(T, [H|Cur]); get_line([], _) -> need_more. mime_type(FileName) -> mime_type(get(sc), FileName). mime_type(S, FileName) -> case filename:extension(FileName) of [_|T] -> element(2, mime_types:t(S, T)); [] -> element(2, mime_types:t(S, [])) end. %% Asynchronously delivery stream_chunk_deliver(YawsPid, Data) -> YawsPid ! {streamcontent, Data}. %% Use timeout here to guard against bug in the SSL application %% that apparently does not close the socket in between %% ssl_esock and erlang (FIN_WAIT2 resp. CLOSE_WAIT). %% Thus, the stream process hangs forever... -define(STREAM_GARBAGE_TIMEOUT, 3600000). % 1 hour %% Synchronous (on ultimate gen_tcp:send) delivery %% Returns: ok | {error, Rsn} stream_chunk_deliver_blocking(YawsPid, Data) -> Ref = erlang:monitor(process, YawsPid), YawsPid ! {streamcontent_with_ack, self(), Data}, receive {YawsPid, streamcontent_ack} -> erlang:demonitor(Ref), %% flush incase a DOWN message was sent before the demonitor call receive {'DOWN', Ref, _, _, _} -> ok after 0 -> ok end; {'DOWN', Ref, _, _, Info} -> {error, {ypid_crash, Info}} after ?STREAM_GARBAGE_TIMEOUT -> %% Killing (unless this function is caught) process tree but %% NOTE that as this is probably due to the OTP SSL application %% not managing to close the socket (FIN_WAIT2 %% resp. CLOSE_WAIT) the SSL process is not killed (it traps %% exit signals) and thus we will leak one file descriptor. error_logger:error_msg( "~p:stream_chunk_deliver_blocking/2 STREAM_GARBAGE_TIMEOUT " "(default 1 hour). Killing ~p", [?MODULE, YawsPid]), erlang:error(stream_garbage_timeout, [YawsPid, Data]) end. stream_chunk_end(YawsPid) -> YawsPid ! endofstreamcontent. stream_process_deliver({ssl, SslSock}, IoList) -> ssl:send(SslSock, IoList); stream_process_deliver(Sock, IoList) -> gen_tcp:send(Sock, IoList). stream_process_deliver_chunk(Sock, IoList) -> Chunk = case erlang:iolist_size(IoList) of 0 -> stream_process_deliver_final_chunk(Sock, IoList); S -> [yaws:integer_to_hex(S), "\r\n", IoList, "\r\n"] end, stream_process_deliver(Sock, Chunk). stream_process_deliver_final_chunk(Sock, IoList) -> Chunk = case erlang:iolist_size(IoList) of 0 -> <<"0\r\n\r\n">>; S -> [yaws:integer_to_hex(S), "\r\n", IoList, "\r\n0\r\n\r\n"] end, stream_process_deliver(Sock, Chunk). stream_process_end(closed, YawsPid) -> YawsPid ! {endofstreamcontent, closed}; stream_process_end({ssl, SslSock}, YawsPid) -> ssl:controlling_process(SslSock, YawsPid), YawsPid ! endofstreamcontent; stream_process_end(Sock, YawsPid) -> gen_tcp:controlling_process(Sock, YawsPid), YawsPid ! endofstreamcontent. %% Pid must be the process in control of the websocket connection. websocket_send(Pid, {Type, Data}) when is_pid(Pid) -> yaws_websockets:send(Pid, {Type, Data}); websocket_send(Pid, #ws_frame{}=Frame) when is_pid(Pid) -> yaws_websockets:send(Pid, Frame). websocket_close(#ws_state{}=WSState) -> yaws_websockets:close(WSState, normal); websocket_close(Pid) when is_pid(Pid) -> yaws_websockets:close(Pid, normal). websocket_close(#ws_state{}=WSState, Reason) -> yaws_websockets:close(WSState, Reason); websocket_close(Pid, Reason) when is_pid(Pid) -> yaws_websockets:close(Pid, Reason). %% returns {ok, SSL socket} if an SSL socket, undefined otherwise get_sslsocket({ssl, SslSocket}) -> {ok, SslSocket}; get_sslsocket(_Socket) -> undefined. %% Return new cookie string new_cookie_session(Opaque) -> yaws_session_server:new_session(Opaque). new_cookie_session(Opaque, TTL) -> yaws_session_server:new_session(Opaque, TTL). new_cookie_session(Opaque, TTL, Cleanup) -> yaws_session_server:new_session(Opaque, TTL, Cleanup). %% as returned in #ysession.cookie cookieval_to_opaque(CookieVal) -> yaws_session_server:cookieval_to_opaque(CookieVal). print_cookie_sessions() -> yaws_session_server:print_sessions(). replace_cookie_session(Cookie, NewOpaque) -> yaws_session_server:replace_session(Cookie, NewOpaque). replace_cookie_session(Cookie, NewOpaque, Cleanup) -> yaws_session_server:replace_session(Cookie, NewOpaque, Cleanup). delete_cookie_session(Cookie) -> yaws_session_server:delete_session(Cookie). lmap(F, [H|T]) -> [lists:map(F, H) | lmap(F, T)]; lmap(_, []) -> []. %% interactively turn on|off tracing set_trace(Val) -> Str = yaws_ctl:actl_trace(Val), io:format("~s", [Str]). set_access_log(Bool) -> {ok, GC, Groups} = getconf(), Groups2 = lmap(fun(SC) -> ?sc_set_access_log(SC, Bool) end, Groups), setconf(GC, Groups2). %% interactively turn on|off tracing to the tty (as well) %% typically useful in embedded mode set_tty_trace(Bool) -> yaws_trace:set_tty_trace(Bool). set_status_code(Code) -> {status, Code}. %% returns [ Header1, Header2 .....] reformat_header(H) -> FormatFun = fun(Hname, {multi, Values}) -> [lists:flatten(io_lib:format("~s: ~s", [Hname, Val])) || Val <- Values]; (Hname, Str) -> lists:flatten(io_lib:format("~s: ~s", [Hname, Str])) end, reformat_header(H, FormatFun). reformat_header(H, FormatFun) -> lists:zf(fun({Hname, Str}) -> I = FormatFun(Hname, Str), {true, I}; (undefined) -> false end, [ if H#headers.connection == undefined -> undefined; true -> {"Connection", H#headers.connection} end, if H#headers.accept == undefined -> undefined; true -> {"Accept", H#headers.accept} end, if H#headers.host == undefined -> undefined; true -> {"Host", H#headers.host} end, if H#headers.if_modified_since == undefined -> undefined; true -> {"If-Modified-Since", H#headers.if_modified_since} end, if H#headers.if_match == undefined -> undefined; true -> {"If-Match", H#headers.if_match} end, if H#headers.if_none_match == undefined -> undefined; true -> {"If-None-Match", H#headers.if_none_match} end, if H#headers.if_range == undefined -> undefined; true -> {"If-Range", H#headers.if_range} end, if H#headers.if_unmodified_since == undefined -> undefined; true -> {"If-Unmodified-Since", H#headers.if_unmodified_since} end, if H#headers.range == undefined -> undefined; true -> {"Range", H#headers.range} end, if H#headers.referer == undefined -> undefined; true -> {"Referer", H#headers.referer} end, if H#headers.user_agent == undefined -> undefined; true -> {"User-Agent", H#headers.user_agent} end, if H#headers.accept_ranges == undefined -> undefined; true -> {"Accept-Ranges", H#headers.accept_ranges} end, if H#headers.cookie == [] -> undefined; true -> {"Cookie", H#headers.cookie} end, if H#headers.keep_alive == undefined -> undefined; true -> {"Keep-Alive", H#headers.keep_alive} end, if H#headers.content_length == undefined -> undefined; true -> {"Content-Length", H#headers.content_length} end, if H#headers.content_type == undefined -> undefined; true -> {"Content-Type", H#headers.content_type} end, if H#headers.content_encoding == undefined -> undefined; true -> {"Content-Encoding", H#headers.content_encoding} end, if H#headers.authorization == undefined -> undefined; true -> {"Authorization", element(3, H#headers.authorization)} end, if H#headers.transfer_encoding == undefined -> undefined; true -> {"Transfer-Encoding", H#headers.transfer_encoding} end, if H#headers.location == undefined -> undefined; true -> {"Location", H#headers.location} end, if H#headers.x_forwarded_for == undefined -> undefined; true -> {"X-Forwarded-For", H#headers.x_forwarded_for} end ] ) ++ lists:map( fun({http_header,_,K,_,V}) -> FormatFun(K,V) end, H#headers.other). set_header(#headers{}=Hdrs, {Header, Value}) -> set_header(Hdrs, Header, Value). set_header(#headers{}=Hdrs, connection, Value) -> Hdrs#headers{connection = Value}; set_header(#headers{}=Hdrs, {lower, "connection"}, Value) -> Hdrs#headers{connection = Value}; set_header(#headers{}=Hdrs, accept, Value) -> Hdrs#headers{accept = Value}; set_header(#headers{}=Hdrs, {lower, "accept"}, Value) -> Hdrs#headers{accept = Value}; set_header(#headers{}=Hdrs, host, Value) -> Hdrs#headers{host = Value}; set_header(#headers{}=Hdrs, {lower, "host"}, Value) -> Hdrs#headers{host = Value}; set_header(#headers{}=Hdrs, if_modified_since, Value) -> Hdrs#headers{if_modified_since = Value}; set_header(#headers{}=Hdrs, {lower, "if-modified-since"}, Value) -> Hdrs#headers{if_modified_since = Value}; set_header(#headers{}=Hdrs, if_match, Value) -> Hdrs#headers{if_match = Value}; set_header(#headers{}=Hdrs, {lower, "if-match"}, Value) -> Hdrs#headers{if_match = Value}; set_header(#headers{}=Hdrs, if_none_match, Value) -> Hdrs#headers{if_none_match = Value}; set_header(#headers{}=Hdrs, {lower, "if-none-match"}, Value) -> Hdrs#headers{if_none_match = Value}; set_header(#headers{}=Hdrs, if_range, Value) -> Hdrs#headers{if_range = Value}; set_header(#headers{}=Hdrs, {lower, "if-range"}, Value) -> Hdrs#headers{if_range = Value}; set_header(#headers{}=Hdrs, if_unmodified_since, Value) -> Hdrs#headers{if_unmodified_since = Value}; set_header(#headers{}=Hdrs, {lower, "if-unmodified-since"}, Value) -> Hdrs#headers{if_unmodified_since = Value}; set_header(#headers{}=Hdrs, range, Value) -> Hdrs#headers{range = Value}; set_header(#headers{}=Hdrs, {lower, "range"}, Value) -> Hdrs#headers{range = Value}; set_header(#headers{}=Hdrs, referer, Value) -> Hdrs#headers{referer = Value}; set_header(#headers{}=Hdrs, {lower, "referer"}, Value) -> Hdrs#headers{referer = Value}; set_header(#headers{}=Hdrs, user_agent, Value) -> Hdrs#headers{user_agent = Value}; set_header(#headers{}=Hdrs, {lower, "user-agent"}, Value) -> Hdrs#headers{user_agent = Value}; set_header(#headers{}=Hdrs, accept_ranges, Value) -> Hdrs#headers{accept_ranges = Value}; set_header(#headers{}=Hdrs, {lower, "accept-ranges"}, Value) -> Hdrs#headers{accept_ranges = Value}; set_header(#headers{}=Hdrs, cookie, Value) -> Hdrs#headers{cookie = Value}; set_header(#headers{}=Hdrs, {lower, "cookie"}, Value) -> Hdrs#headers{cookie = Value}; set_header(#headers{}=Hdrs, keep_alive, Value) -> Hdrs#headers{keep_alive = Value}; set_header(#headers{}=Hdrs, {lower, "keep-alive"}, Value) -> Hdrs#headers{keep_alive = Value}; set_header(#headers{}=Hdrs, location, Value) -> Hdrs#headers{location = Value}; set_header(#headers{}=Hdrs, {lower, "location"}, Value) -> Hdrs#headers{location = Value}; set_header(#headers{}=Hdrs, content_length, Value) -> Hdrs#headers{content_length = Value}; set_header(#headers{}=Hdrs, {lower, "content-length"}, Value) -> Hdrs#headers{content_length = Value}; set_header(#headers{}=Hdrs, content_type, Value) -> Hdrs#headers{content_type = Value}; set_header(#headers{}=Hdrs, {lower, "content-type"}, Value) -> Hdrs#headers{content_type = Value}; set_header(#headers{}=Hdrs, content_encoding, Value) -> Hdrs#headers{content_encoding = Value}; set_header(#headers{}=Hdrs, {lower, "content-encoding"}, Value) -> Hdrs#headers{content_encoding = Value}; set_header(#headers{}=Hdrs, authorization, Value) -> Hdrs#headers{authorization = Value}; set_header(#headers{}=Hdrs, {lower, "authorization"}, Value) -> Hdrs#headers{authorization = Value}; set_header(#headers{}=Hdrs, transfer_encoding, Value) -> Hdrs#headers{transfer_encoding = Value}; set_header(#headers{}=Hdrs, {lower, "transfer-encoding"}, Value) -> Hdrs#headers{transfer_encoding = Value}; set_header(#headers{}=Hdrs, x_forwarded_for, Value) -> Hdrs#headers{x_forwarded_for = Value}; set_header(#headers{}=Hdrs, {lower, "x-forwarded-for"}, Value) -> Hdrs#headers{x_forwarded_for = Value}; set_header(#headers{}=Hdrs, Header, Value) when is_atom(Header) -> set_header(Hdrs, atom_to_list(Header), Value); set_header(#headers{}=Hdrs, Header, Value) when is_binary(Header) -> set_header(Hdrs, binary_to_list(Header), Value); set_header(#headers{}=Hdrs, Header, Val) when is_binary(Val) -> set_header(Hdrs, {lower, string:to_lower(Header)}, binary_to_list(Val)); set_header(#headers{other=Other}=Hdrs, {lower, Header}, undefined) -> Handler = fun(_, true, Acc) -> Acc; (HdrVal, false, Acc) -> [HdrVal|Acc] end, NewOther = fold_others(Header, Handler, Other, []), Hdrs#headers{other = lists:reverse(NewOther)}; set_header(#headers{other=Other}=Hdrs, {lower, Header}, Val) -> HdrName = erlang_header_name(Header), Handler = fun({http_header, Int, _, Rsv, _}, true, {Acc, _}) -> {[{http_header, Int, HdrName, Rsv, Val}|Acc],true}; (HdrVal, false, {Acc, Found}) -> {[HdrVal|Acc], Found} end, {NewOther0, Found} = fold_others(Header, Handler, Other, {[], false}), NewOther = case Found of true -> NewOther0; false -> [{http_header, 0, HdrName, undefined, Val}|NewOther0] end, Hdrs#headers{other = lists:reverse(NewOther)}; set_header(#headers{}=Hdrs, Header, undefined) -> set_header(Hdrs, {lower, string:to_lower(Header)}, undefined); set_header(#headers{}=Hdrs, Header, Value) -> set_header(Hdrs, {lower, string:to_lower(Header)}, Value). merge_header(#headers{}=Hdrs, {Header, Value}) -> merge_header(Hdrs, Header, Value). merge_header(#headers{}=Hdrs, _Header, undefined) -> Hdrs; merge_header(#headers{}=Hdrs, Header, Value) when is_atom(Header) -> merge_header(Hdrs, atom_to_list(Header), Value); merge_header(#headers{}=Hdrs, Header, Value) when is_binary(Header) -> merge_header(Hdrs, binary_to_list(Header), Value); merge_header(#headers{}=Hdrs, Header, Value) when is_binary(Value) -> merge_header(Hdrs, Header, binary_to_list(Value)); merge_header(Hdrs, {lower, "set-cookie"}=LHdr, Value) -> NewValue = case get_header(Hdrs, LHdr) of undefined -> {multi, [Value]}; {multi, MultiVal} -> {multi, MultiVal ++ [Value]}; ExistingValue -> {multi, [ExistingValue, Value]} end, set_header(Hdrs, LHdr, NewValue); merge_header(Hdrs, {lower, _Header}=LHdr, Value) -> NewValue = case get_header(Hdrs, LHdr) of undefined -> Value; ExistingValue -> ExistingValue ++ ", " ++ Value end, set_header(Hdrs, LHdr, NewValue); merge_header(#headers{}=Hdrs, Header, Value) -> merge_header(Hdrs, {lower, string:to_lower(Header)}, Value). get_header(#headers{}=Hdrs, connection) -> Hdrs#headers.connection; get_header(#headers{}=Hdrs, {lower, "connection"}) -> Hdrs#headers.connection; get_header(#headers{}=Hdrs, accept) -> Hdrs#headers.accept; get_header(#headers{}=Hdrs, {lower, "accept"}) -> Hdrs#headers.accept; get_header(#headers{}=Hdrs, host) -> Hdrs#headers.host; get_header(#headers{}=Hdrs, {lower, "host"}) -> Hdrs#headers.host; get_header(#headers{}=Hdrs, if_modified_since) -> Hdrs#headers.if_modified_since; get_header(#headers{}=Hdrs, {lower, "if-modified-since"}) -> Hdrs#headers.if_modified_since; get_header(#headers{}=Hdrs, if_match) -> Hdrs#headers.if_match; get_header(#headers{}=Hdrs, {lower, "if-match"}) -> Hdrs#headers.if_match; get_header(#headers{}=Hdrs, if_none_match) -> Hdrs#headers.if_none_match; get_header(#headers{}=Hdrs, {lower, "if-none-match"}) -> Hdrs#headers.if_none_match; get_header(#headers{}=Hdrs, if_range) -> Hdrs#headers.if_range; get_header(#headers{}=Hdrs, {lower, "if-range"}) -> Hdrs#headers.if_range; get_header(#headers{}=Hdrs, if_unmodified_since) -> Hdrs#headers.if_unmodified_since; get_header(#headers{}=Hdrs, {lower, "if-unmodified-since"}) -> Hdrs#headers.if_unmodified_since; get_header(#headers{}=Hdrs, range) -> Hdrs#headers.range; get_header(#headers{}=Hdrs, {lower, "range"}) -> Hdrs#headers.range; get_header(#headers{}=Hdrs, referer) -> Hdrs#headers.referer; get_header(#headers{}=Hdrs, {lower, "referer"}) -> Hdrs#headers.referer; get_header(#headers{}=Hdrs, user_agent) -> Hdrs#headers.user_agent; get_header(#headers{}=Hdrs, {lower, "user-agent"}) -> Hdrs#headers.user_agent; get_header(#headers{}=Hdrs, accept_ranges) -> Hdrs#headers.accept_ranges; get_header(#headers{}=Hdrs, {lower, "accept-ranges"}) -> Hdrs#headers.accept_ranges; get_header(#headers{}=Hdrs, cookie) -> Hdrs#headers.cookie; get_header(#headers{}=Hdrs, {lower, "cookie"}) -> Hdrs#headers.cookie; get_header(#headers{}=Hdrs, keep_alive) -> Hdrs#headers.keep_alive; get_header(#headers{}=Hdrs, {lower, "keep-alive"}) -> Hdrs#headers.keep_alive; get_header(#headers{}=Hdrs, location) -> Hdrs#headers.location; get_header(#headers{}=Hdrs, {lower, "location"}) -> Hdrs#headers.location; get_header(#headers{}=Hdrs, content_length) -> Hdrs#headers.content_length; get_header(#headers{}=Hdrs, {lower, "content-length"}) -> Hdrs#headers.content_length; get_header(#headers{}=Hdrs, content_type) -> Hdrs#headers.content_type; get_header(#headers{}=Hdrs, {lower, "content-type"}) -> Hdrs#headers.content_type; get_header(#headers{}=Hdrs, content_encoding) -> Hdrs#headers.content_encoding; get_header(#headers{}=Hdrs, {lower, "content-encoding"}) -> Hdrs#headers.content_encoding; get_header(#headers{}=Hdrs, authorization) -> Hdrs#headers.authorization; get_header(#headers{}=Hdrs, {lower, "authorization"}) -> Hdrs#headers.authorization; get_header(#headers{}=Hdrs, transfer_encoding) -> Hdrs#headers.transfer_encoding; get_header(#headers{}=Hdrs, {lower, "transfer-encoding"}) -> Hdrs#headers.transfer_encoding; get_header(#headers{}=Hdrs, x_forwarded_for) -> Hdrs#headers.x_forwarded_for; get_header(#headers{}=Hdrs, {lower, "x-forwarded-for"}) -> Hdrs#headers.x_forwarded_for; get_header(#headers{}=Hdrs, Header) when is_atom(Header) -> get_header(Hdrs, atom_to_list(Header)); get_header(#headers{}=Hdrs, Header) when is_binary(Header) -> get_header(Hdrs, binary_to_list(Header)); get_header(#headers{other = Other}, {lower, Header}) -> Handler = fun({http_header, _, _, _, Value}, true, _Acc) -> throw(Value); (_, false, Acc) -> Acc end, catch fold_others(Header, Handler, Other, undefined); get_header(#headers{}=Hdrs, Header) -> get_header(Hdrs, {lower, string:to_lower(Header)}). get_header(#headers{}=Hdrs, Header, Default) -> case get_header(Hdrs, Header) of undefined -> Default; Value -> Value end. delete_header(#headers{}=Hdrs, Header) -> set_header(Hdrs, Header, undefined). %% assumes that LowerHdr is already downcased fold_others(LowerHdr, Handler, Other, StartAcc) -> lists:foldl(fun({http_header, _, Hdr, _, _}=HdrVal, Acc) -> HdrNm = string:to_lower( if is_atom(Hdr) -> atom_to_list(Hdr); is_binary(Hdr) -> binary_to_list(Hdr); true -> Hdr end), Handler(HdrVal, HdrNm == LowerHdr, Acc) end, StartAcc, Other). erlang_header_name("cache-control") -> 'Cache-Control'; erlang_header_name("date") -> 'Date'; erlang_header_name("pragma") -> 'Pragma'; erlang_header_name("upgrade") -> 'Upgrade'; erlang_header_name("via") -> 'Via'; erlang_header_name("accept-charset") -> 'Accept-Charset'; erlang_header_name("accept-encoding") -> 'Accept-Encoding'; erlang_header_name("accept-language") -> 'Accept-Language'; erlang_header_name("from") -> 'From'; erlang_header_name("max-forwards") -> 'Max-Forwards'; erlang_header_name("proxy-authorization") -> 'Proxy-Authorization'; erlang_header_name("age") -> 'Age'; erlang_header_name("proxy-authenticate") -> 'Proxy-Authenticate'; erlang_header_name("public") -> 'Public'; erlang_header_name("retry-after") -> 'Retry-After'; erlang_header_name("server") -> 'Server'; erlang_header_name("vary") -> 'Vary'; erlang_header_name("warning") -> 'Warning'; erlang_header_name("www-authenticate") -> 'Www-Authenticate'; erlang_header_name("allow") -> 'Allow'; erlang_header_name("content-base") -> 'Content-Base'; erlang_header_name("content-encoding") -> 'Content-Encoding'; erlang_header_name("content-language") -> 'Content-Language'; erlang_header_name("content-location") -> 'Content-Location'; erlang_header_name("content-md5") -> 'Content-Md5'; erlang_header_name("content-range") -> 'Content-Range'; erlang_header_name("etag") -> 'Etag'; erlang_header_name("expires") -> 'Expires'; erlang_header_name("last-modified") -> 'Last-Modified'; erlang_header_name("set-cookie") -> 'Set-Cookie'; erlang_header_name("set-cookie2") -> 'Set-Cookie2'; erlang_header_name("proxy-connection") -> 'Proxy-Connection'; erlang_header_name(Name) -> capitalize_header(Name). capitalize_header(Name) -> %% Before R16B Erlang capitalized words inside header names only for %% headers less than 20 characters long. In R16B that length was raised %% to 50. Using decode_packet lets us be portable. {ok, {http_header, _, Result, _, _}, _} = erlang:decode_packet(httph, list_to_binary([Name, <<": x\r\n\r\n">>]), []), Result. reformat_request(#http_request{method = bad_request}) -> ["Bad request"]; reformat_request(Req) -> Path = case Req#http_request.path of {abs_path, AbsPath} -> AbsPath; {absoluteURI, _Scheme, _Host0, _Port, RawPath} -> RawPath end, {Maj, Min} = Req#http_request.version, [yaws:to_list(Req#http_request.method), " ", Path," HTTP/", integer_to_list(Maj),".", integer_to_list(Min)]. reformat_response(Resp) -> {Maj,Min} = Resp#http_response.version, ["HTTP/",integer_to_list(Maj),".", integer_to_list(Min), " ", integer_to_list(Resp#http_response.status), " ", Resp#http_response.phrase]. %% stringify the scheme://host[:port] part of a #url reformat_url(U) -> [yaws:to_string(U#url.scheme), "://", U#url.host, if U#url.port == undefined -> []; true -> [$: | integer_to_list(U#url.port)] end]. set_content_type(MimeType) -> {header, {content_type, MimeType}}. %% returns a #url{} record parse_url(Str) -> parse_url(Str, strict). parse_url(Str, Strict) -> case Str of "http://" ++ Rest -> parse_url(host, Strict, #url{scheme = http}, Rest, []); "https://" ++ Rest -> parse_url(host, Strict, #url{scheme = https}, Rest, []); "ftp://" ++ Rest -> parse_url(host, Strict, #url{scheme = ftp}, Rest, []); "file://" ++ Rest -> parse_url(host, Strict, #url{scheme = file}, Rest, []); _ when Strict == sloppy -> parse_url(host, Strict, #url{scheme = undefined}, Str, []) end. parse_url(host, Strict, U, Str, Ack) -> case Str of [] -> U#url{host = lists:reverse(Ack), path = "/" }; [$/|Tail] -> U2 = U#url{host = lists:reverse(Ack)}, parse_url(path, Strict, U2, Tail,"/"); [$:|T] -> U2 = U#url{host = lists:reverse(Ack)}, parse_url(port, Strict, U2, T,[]); [$[|T] -> parse_url(ipv6, Strict, U, T, [$[]); [H|T] -> parse_url(host, Strict, U, T, [H|Ack]) end; parse_url(ipv6, Strict, U, Str, Ack) -> case Str of [$]] -> U#url{host = lists:reverse([$]|Ack]), path = "/" }; [$], $/|T] -> U2 = U#url{host = lists:reverse([$]|Ack])}, parse_url(path, Strict, U2, T,"/"); [$], $:|T] -> U2 = U#url{host = lists:reverse([$]|Ack])}, parse_url(port, Strict, U2, T,[]); [H|T] -> parse_url(ipv6, Strict, U, T, [H|Ack]) end; parse_url(port, Strict, U, Str, Ack) -> case Str of [] -> U#url{port = list_to_integer(lists:reverse(Ack)), path = "/"}; [$/|T] -> U2 = U#url{port = list_to_integer(lists:reverse(Ack))}, parse_url(path, Strict, U2, T,"/"); [H|T] -> parse_url(port, Strict, U,T,[H|Ack]) end; parse_url(path, Strict, U, Str, Ack) -> case Str of [] -> U#url{path = lists:reverse(Ack)}; [$?|T] -> U#url{path = lists:reverse(Ack), querypart = T}; [H|T] -> parse_url(path, Strict, U, T, [H|Ack]) end. %% used to construct redir headers from partial URLs such %% as e.g. /foo/bar format_partial_url(Url, SC) -> [if Url#url.scheme == undefined -> yaws:redirect_scheme(SC); true -> yaws:to_string(Url#url.scheme) ++ "://" end, if Url#url.host == undefined orelse Url#url.host == [] -> yaws:redirect_host(SC, undefined); true -> Url#url.host end, if Url#url.port == undefined -> []; true -> [$: | integer_to_list(Url#url.port)] end, Url#url.path, if Url#url.querypart == [] -> []; true -> [$?|Url#url.querypart] end ]. format_url(Url) when is_record(Url, url) -> [ if Url#url.scheme == undefined -> "http://"; true -> yaws:to_string(Url#url.scheme) ++ "://" end, Url#url.host, if Url#url.port == undefined -> []; true -> [$: | integer_to_list(Url#url.port)] end, Url#url.path, if Url#url.querypart == [] -> []; true -> [$?|Url#url.querypart] end ]. is_absolute_URI([C|T]) when ((C>=$a) and (C=<$z)) or ((C>=$A) and (C=<$Z))-> is_abs_URI1(T); is_absolute_URI(_) -> false. is_abs_URI1([$:|_]) -> true; is_abs_URI1([C|T]) when ((C>=$a) and (C=<$z)) or ((C>=$A) and (C=<$Z)) or ((C>=$0) and (C=<$9)) or (C==$+) or (C==$-) or (C==$.) -> is_abs_URI1(T); is_abs_URI1(_) -> false. %% ------------------------------------------------------------ %% simple erlang term representation of HTML: %% EHTML = [EHTML] | {Tag, Attrs, Body} | {Tag, Attrs} | {Tag} | %% {Module, Fun, [Args]} | fun/0 | %% binary() | character() %% Tag = atom() %% Attrs = [{Key, Value}] %% Key = atom() %% Value = string() | binary() | atom() | integer() | float() | %% {Module, Fun, [Args]} | fun/0 %% Body = EHTML ehtml_expand(Ch) when Ch >= 0, Ch =< 255 -> Ch; %yaws_api:htmlize_char(Ch); ehtml_expand(Bin) when is_binary(Bin) -> Bin; % yaws_api:htmlize(Bin); ehtml_expand({ssi,File, Del, Bs}) -> case yaws_server:ssi(File, Del, Bs) of {error, Rsn} -> io_lib:format("ERROR: ~p~n",[Rsn]); X -> X end; %%!todo (low priority) - investigate whether tail-recursion would be of any %% benefit here instead of the current ehtml_expand(Body) recursion. %% - provide a tail_recursive version & add a file in the %% benchmarks folder to measure it. % ehtml_expand({Tag}) -> ["<", atom_to_list(Tag), ehtml_end_tag(Tag)]; ehtml_expand({pre_html, X}) -> X; ehtml_expand({Mod, Fun, Args}) when is_atom(Mod), is_atom(Fun), is_list(Args) -> ehtml_expand(Mod:Fun(Args)); ehtml_expand({Tag, Attrs}) -> NL = ehtml_nl(Tag), [NL, "<", atom_to_list(Tag), ehtml_attrs(Attrs), ehtml_end_tag(Tag)]; ehtml_expand({Tag, Attrs, Body}) when is_atom(Tag) -> Ts = atom_to_list(Tag), NL = ehtml_nl(Tag), [NL, "<", Ts, ehtml_attrs(Attrs), ">", ehtml_expand(Body), ""]; ehtml_expand([H|T]) -> [ehtml_expand(H)|ehtml_expand(T)]; ehtml_expand([]) -> []; ehtml_expand(Fun) when is_function(Fun) -> ehtml_expand(Fun()). ehtml_attrs([]) -> []; ehtml_attrs([Attribute|Tail]) when is_atom(Attribute) -> [[$ |atom_to_list(Attribute)]|ehtml_attrs(Tail)]; ehtml_attrs([Attribute|Tail]) when is_list(Attribute) -> [" ", Attribute|ehtml_attrs(Tail)]; ehtml_attrs([{Name, {Mod, Fun, Args}} | Tail]) when is_atom(Mod), is_atom(Fun), is_list(Args) -> ehtml_attrs([{Name, Mod:Fun(Args)} | Tail]); ehtml_attrs([{Name, Value} | Tail]) when is_function(Value) -> ehtml_attrs([{Name, Value()} | Tail]); ehtml_attrs([{Name, Value} | Tail]) -> ValueString = [$", value2string(Value), $"], [[$ |atom_to_list(Name)], [$=|ValueString]|ehtml_attrs(Tail)]; ehtml_attrs([{check, Name, {Mod, Fun, Args}} | Tail]) when is_atom(Mod), is_atom(Fun), is_list(Args) -> ehtml_attrs([{check, Name, Mod:Fun(Args)} | Tail]); ehtml_attrs([{check, Name, Value} | Tail]) when is_function(Value) -> ehtml_attrs([{check, Name, Value()} | Tail]); ehtml_attrs([{check, Name, Value} | Tail]) -> Val = value2string(Value), Q = case deepmember($", Val) of true -> $'; false -> $" end, ValueString = [Q,Val,Q], [[$ |atom_to_list(Name)], [$=|ValueString]|ehtml_attrs(Tail)]. value2string(Atom) when is_atom(Atom) -> atom_to_list(Atom); value2string(String) when is_list(String) -> String; value2string(Binary) when is_binary(Binary) -> Binary; value2string(Integer) when is_integer(Integer) -> integer_to_list(Integer); value2string(Float) when is_float(Float) -> float_to_list(Float). %% Tags for which we must not add extra white space. %% FIXME: should there be anything more in this list? ehtml_nl(a) -> []; ehtml_nl(br) -> []; ehtml_nl(span) -> []; ehtml_nl(em) -> []; ehtml_nl(strong) -> []; ehtml_nl(dfn) -> []; ehtml_nl(code) -> []; ehtml_nl(samp) -> []; ehtml_nl(kbd) -> []; ehtml_nl(var) -> []; ehtml_nl(cite) -> []; ehtml_nl(abbr) -> []; ehtml_nl(acronym) -> []; ehtml_nl(q) -> []; ehtml_nl(sub) -> []; ehtml_nl(sup) -> []; ehtml_nl(ins) -> []; ehtml_nl(del) -> []; ehtml_nl(img) -> []; ehtml_nl(tt) -> []; ehtml_nl(i) -> []; ehtml_nl(b) -> []; ehtml_nl(big) -> []; ehtml_nl(small) -> []; ehtml_nl(strike) -> []; ehtml_nl(s) -> []; ehtml_nl(u) -> []; ehtml_nl(font) -> []; ehtml_nl(basefont) -> []; ehtml_nl(input) -> []; ehtml_nl(button) -> []; ehtml_nl(object) -> []; ehtml_nl(_) -> "\n". %% Void elements must not have an end tag () in HTML5, while for most %% elements a proper end tag (, not ) is mandatory. %% %% http://www.w3.org/TR/html5/syntax.html#void-elements %% http://www.w3.org/TR/html5/syntax.html#syntax-tag-omission -define(self_closing, " />"). % slash ignored in HTML5 ehtml_end_tag(area) -> ?self_closing; ehtml_end_tag(base) -> ?self_closing; ehtml_end_tag(br) -> ?self_closing; ehtml_end_tag(col) -> ?self_closing; ehtml_end_tag(embed) -> ?self_closing; ehtml_end_tag(hr) -> ?self_closing; ehtml_end_tag(img) -> ?self_closing; ehtml_end_tag(input) -> ?self_closing; ehtml_end_tag(keygen) -> ?self_closing; ehtml_end_tag(link) -> ?self_closing; ehtml_end_tag(meta) -> ?self_closing; ehtml_end_tag(param) -> ?self_closing; ehtml_end_tag(source) -> ?self_closing; ehtml_end_tag(track) -> ?self_closing; ehtml_end_tag(wbr) -> ?self_closing; ehtml_end_tag(Tag) -> [">"]. %% ------------------------------------------------------------ %% ehtml_expander/1: an EHTML optimizer %% %% This is an optimization for generating the same EHTML multiple times with %% only small differences, by using fast re-usable templates that contain %% variables. The variables are atoms starting with a dollar sign, like %% '$myvar'. There are two functions: ehtml_expander/1 to create an optimized %% EHTML template, then ehtml_apply/2 takes a template and a dictionary of %% variable values and generates the actual HTML. %% %% If you are spending a lot of time regenerating similar EHTML fragments then %% this is for you. %% %% Variables can appear in three places: %% - As a body element, where you would normally have a tag. The values of %% these variables are expanded as EHTML. %% - As the name or value of an attribute. The values of these variables are %% strings. %% - As the CDR of an attribute list. The values of these variables are %% key-value lists of more attributes. %% %% See ehtml_expander_test/0 for an example. %% %% The approach is inspired by the way that Yaws already treats .yaws files, %% and the article ``A Hacker's Introduction To Partial Evaluation'' by Darius %% Bacon (cool guy), http://www.lisp-p.org/htdocs/peval/peval.cgi %% %% (For now I flatter myself that this is some kind of partial evaluator, but %% I don't really know :-) -luke) ehtml_expander(X) -> ehtml_expander_compress(flatten(ehtml_expander(X, [], [])), []). %% Returns a deep list of text and variable references (atoms) %% Text ehtml_expander(Ch, Before, After) when Ch >= 0, Ch =< 255 -> ehtml_expander_done(yaws_api:htmlize_char(Ch), Before, After); ehtml_expander(Bin, Before, After) when is_binary(Bin) -> ehtml_expander_done(yaws_api:htmlize(Bin), Before, After); ehtml_expander({ssi,File, Del, Bs}, Before, After) -> Str = case yaws_server:ssi(File, Del, Bs) of {error, Rsn} -> io_lib:format("ERROR: ~p~n",[Rsn]); X -> X end, ehtml_expander_done(Str, Before, After); ehtml_expander({pre_html, X}, Before, After) -> ehtml_expander_done(X, Before, After); %% Tags ehtml_expander({Tag}, Before, After) -> ehtml_expander_done(["<", atom_to_list(Tag), ehtml_end_tag(Tag)], Before, After); ehtml_expander({Tag, Attrs}, Before, After) -> NL = ehtml_nl(Tag), ehtml_expander_done([NL, "<", atom_to_list(Tag), ehtml_attrs(Attrs), ehtml_end_tag(Tag)], Before, After); ehtml_expander({Tag, Attrs, Body}, Before, After) -> ehtml_expander(Body, [["\n<", atom_to_list(Tag), ehtml_attrs_expander(Attrs), ">"]| Before], [""|After]); %% Variable references ehtml_expander(Var, Before, After) when is_atom(Var) -> [reverse(Before), {ehtml, ehtml_var_name(Var)}, After]; %% Lists ehtml_expander([H|T], Before, After) -> ehtml_expander(T, [ehtml_expander(H, [], [])|Before], After); ehtml_expander([], Before, After) -> ehtml_expander_done("", Before, After). %% Expander for attributes. The attribute name and value can each be a %% variable reference. ehtml_attrs_expander([]) -> ""; ehtml_attrs_expander([{Var,Val}|T]) -> [[" ", ehtml_attr_part_expander(Var), "=", "\"", ehtml_attr_part_expander(Val), "\""]| ehtml_attrs_expander(T)]; ehtml_attrs_expander([Var|T]) -> [[" ", ehtml_attr_part_expander(Var)]| ehtml_attrs_expander(T)]; ehtml_attrs_expander(Var) when is_atom(Var) -> %% Var in the cdr of an attribute list [{ehtml_attrs, ehtml_var_name(Var)}]. ehtml_attr_part_expander(A) when is_atom(A) -> case atom_to_list(A) of [$$|_Rest] -> {preformatted, ehtml_var_name(A)}; Other -> Other end; ehtml_attr_part_expander(I) when is_integer(I) -> integer_to_list(I); ehtml_attr_part_expander(S) when is_list(S) -> S. ehtml_expander_done(X, Before, After) -> [reverse([X|Before]), After]. %% Compress an EHTML expander, converting all adjacent bits of text into %% binaries. %% Returns: [binary() | {ehtml, Var} | {preformatted, Var}, {ehtml_attrs, Var}] %% Var = atom() ehtml_expander_compress([Tag|T], Acc) when is_tuple(Tag) -> [list_to_binary(reverse(Acc)), Tag | ehtml_expander_compress(T, [])]; ehtml_expander_compress([], Acc) -> [list_to_binary(reverse(Acc))]; ehtml_expander_compress([H|T], Acc) when is_integer(H) -> ehtml_expander_compress(T, [H|Acc]). %% Apply an expander with the variable bindings in Env. Env is a list of %% {VarName, Value} tuples, where VarName is an atom and Value is an ehtml %% term. ehtml_apply(Expander, Env) -> [ehtml_eval(X, Env) || X <- Expander]. ehtml_eval(Bin, _Env) when is_binary(Bin) -> Bin; ehtml_eval({Type, Var}, Env) -> case lists:keysearch(Var, 1, Env) of false -> erlang:error({ehtml_unbound, Var}); {value, {Var, Val}} -> case Type of ehtml -> ehtml_expand(Val); preformatted -> Val; ehtml_attrs -> ehtml_attrs(Val) end end. %% Get the name part of a variable reference. %% e.g. ehtml_var_name('$foo') -> foo. ehtml_var_name(A) when is_atom(A) -> case atom_to_list(A) of [$$|Rest] -> list_to_atom(Rest); _Other -> erlang:error({bad_ehtml_var_name, A}) end. ehtml_expander_test() -> %% Expr is a template containing variables. Expr = {html, [{title, '$title'}], {body, [], [{h1, [], '$heading'}, '$text']}}, %% Expand is an expander that can be used to quickly generate the HTML %% specified in Expr. Expand = ehtml_expander(Expr), %% Bs{1,2} are lists of variable bindings to fill in the gaps in the %% template. We can reuse the template on many sets of bindings, and this %% is much faster than doing a full ehtml of the whole page each time. Bs1 = [{title, "First page"}, {heading, "Heading"}, {text, {pre_html, "My text!"}}], Bs2 = [{title, "Second page"}, {heading, "Foobar"}, {text, {b, [], "My text again!"}}], %% Page1 and Page2 are generated from the template. They are I/O lists %% (i.e. deep lists of strings and binaries, ready to ship) Page1 = ehtml_apply(Expand, Bs1), Page2 = ehtml_apply(Expand, Bs2), %% We return the two pages as strings, plus the actual expander (which is %% an "opaque" data structure, but maybe interesting to see.) {binary_to_list(list_to_binary(Page1)), binary_to_list(list_to_binary(Page2)), Expand}. %% call_cgi calls the script `Scriptfilename' (full path). If %% `Exefilename' is given, it is the executable to handle this, %% otherwise `Scriptfilame' is assumed to be executable itself. %% %% Note however, that these functions usually generate stream content. %% (If you have good use for a version generating {content, _, _} %% instead, contact carsten@codimi.de) %% %% Also note, that they may return `get_more' and expect to be called %% again. call_cgi(Arg, Scriptfilename) -> yaws_cgi:call_cgi(Arg, Scriptfilename). call_cgi(Arg, Exefilename, Scriptfilename) -> yaws_cgi:call_cgi(Arg, Exefilename, Scriptfilename). %% call_fci_responder issues a responder role call to the FastCGI %% application server. It returns the same return value as out/1. %% %% call_fci_authorizer issues a authorizer role call to the FastCGI %% application server. It returns: %% %% {denied, Out} : Access is denied. Out is the same return value as %% out/1. %% %% {allowed, Variables} : Access is allowed. Variables is a list of %% environment variables returned by the authorization server using %% Variable-XXX: YYY headers. %% %% Note: the FastCGI filter role is not yet supported. %% %% The following information is taken from the server configuration: %% - The hostname (or address) and port number of the application server. %% - Extra CGI variables. %% - Trace FastCGI protocol messages? %% - Log application server error messages? %% %% The caller can optionally provide an Options argument which supports %% the following options. These override the defaults taken from the %% server config. %% %% {app_server_host, string() | ip_address()} : The hostname or IP address %% of the application server. %% %% {app_server_port, int()} : The TCP port number of the application server. %% %% {path_info, string()} : Override the pathinfo string from Arg. %% %% {extra_env, [{string()|binary(), string()|binary()}]} : Extra %% environment variables to be passed to the application server, as a list %% of name-value pairs. %% %% trace_protocol : Trace FastCGI protocol messages. %% %% log_app_error : Log application errors (output to stderr and non-zero %% exit value). %% call_fcgi_responder(Arg) -> yaws_cgi:call_fcgi_responder(Arg). call_fcgi_responder(Arg, Options) -> yaws_cgi:call_fcgi_responder(Arg, Options). call_fcgi_authorizer(Arg) -> yaws_cgi:call_fcgi_authorizer(Arg). call_fcgi_authorizer(Arg, Options) -> yaws_cgi:call_fcgi_authorizer(Arg, Options). %% deepmember(_C,[]) -> false; deepmember(C,[C|_Cs]) -> true; deepmember(C,[L|Cs]) when is_list(L) -> case deepmember(C,L) of true -> true; false -> deepmember(C,Cs) end; deepmember(C,[N|Cs]) when C /= N -> deepmember(C, Cs); deepmember(_C,<<>>) -> false; deepmember(C, <>) -> true; deepmember(C, <<_,Cs/binary>>) -> deepmember(C, Cs). %% . Parse a Set-Cookie header, following the RFC6265: %% %% "Set-Cookie: " set-cookie-string %% set-cookie-string = cookie-pair *( ";" SP cookie-av ) %% cookie-pair = cookie-name "=" cookie-value %% cookie-name = token %% cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) %% cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E %% token = %% %% cookie-av = expires-av / max-age-av / domain-av / path-av / %% secure-av / httponly-av / extension-av %% expires-av = "Expires=" %% max-age-av = "Max-Age=" [1-9] *DIGIT %% domain-av = "Domain=" ; defined in [RFC1034] %% path-av = "Path=" %% secure-av = "Secure" %% httponly-av = "HttpOnly" %% extension-av = %% %% NOTE: in RFC2109 and RFC2965, multiple cookies, separated by comma, can be %% defined in a single header. So, To be backward compatible with these RFCs, %% comma is forbidden in 'path-av' and 'extension-av' except for double-quoted %% value. %% %% %% . Parse a Cookie header, following the RFC6265: %% %% "Cookie: " cookie-string %% cookie-string = cookie-pair *( ";" SP cookie-pair ) %% %% NOTE: To be backward compatible with RFCs, comma is considered as a cookie %% separator, like semicolon. %% parse_set_cookie(Str) -> parse_set_cookie(Str, []). parse_set_cookie([], [SetCookie]) -> SetCookie; parse_set_cookie([], SetCookies) -> lists:reverse(SetCookies); parse_set_cookie(Str, SetCookies) -> case do_parse_set_cookie(Str) of {#setcookie{extensions=Exts}=C0, Rest} -> C1 = C0#setcookie{extensions=lists:reverse(Exts)}, parse_set_cookie(Rest, [C1|SetCookies]); error -> [] end. do_parse_set_cookie(Str) -> {Key, Rest0} = parse_cookie_key(skip_space(Str), []), case yaws:to_lower(Key) of [] -> error; K -> Cookie0 = #setcookie{key=K, quoted=false}, case skip_space(Rest0) of [$=|Rest1] -> {V, Q, Rest2} = parse_cookie_value(skip_space(Rest1)), Cookie1 = Cookie0#setcookie{value=V, quoted=Q}, parse_set_cookie_result(Cookie1, skip_space(Rest2)); [$;|Rest1] -> parse_set_cookie_options(Rest1, Cookie0); [$,|Rest1] -> {Cookie0, Rest1}; [] -> {Cookie0, []}; _ -> error end end. parse_set_cookie_options(Str, Cookie0) -> {Key, Rest0} = parse_cookie_key(skip_space(Str), []), case yaws:to_lower(Key) of [] -> {Cookie0, Rest0}; "domain" -> case skip_space(Rest0) of [$=|Rest1] -> {V,_,Rest2} = parse_set_cookie_domain(skip_space(Rest1),[]), Cookie1 = Cookie0#setcookie{domain=V}, parse_set_cookie_result(Cookie1, skip_space(Rest2)); [$;|Rest1] -> parse_set_cookie_options(Rest1, Cookie0); [$,|Rest1] -> {Cookie0, Rest1}; [] -> {Cookie0, []}; _ -> error end; "max-age" -> case skip_space(Rest0) of [$=|Rest1] -> {V,_,Rest2} = parse_set_cookie_maxage(skip_space(Rest1),[]), Cookie1 = Cookie0#setcookie{max_age=V}, parse_set_cookie_result(Cookie1, skip_space(Rest2)); [$;|Rest1] -> parse_set_cookie_options(Rest1, Cookie0); [$,|Rest1] -> {Cookie0, Rest1}; [] -> {Cookie0, []}; _ -> error end; "expires" -> case skip_space(Rest0) of [$=|Rest1] -> {V, _, Rest2} = parse_set_cookie_expires(skip_space(Rest1)), Cookie1 = Cookie0#setcookie{expires=V}, parse_set_cookie_result(Cookie1, skip_space(Rest2)); [$;|Rest1] -> parse_set_cookie_options(Rest1, Cookie0); [$,|Rest1] -> {Cookie0, Rest1}; [] -> {Cookie0, []}; _ -> error end; "path" -> case skip_space(Rest0) of [$=|Rest1] -> {V, _, Rest2} = parse_cookie_value(skip_space(Rest1)), Cookie1 = Cookie0#setcookie{path=V}, parse_set_cookie_result(Cookie1, skip_space(Rest2)); [$;|Rest1] -> parse_set_cookie_options(Rest1, Cookie0); [$,|Rest1] -> {Cookie0, Rest1}; [] -> {Cookie0, []}; _ -> error end; "secure" -> Cookie1 = Cookie0#setcookie{secure=true}, parse_set_cookie_result(Cookie1, skip_space(Rest0)); "httponly" -> Cookie1 = Cookie0#setcookie{http_only=true}, parse_set_cookie_result(Cookie1, skip_space(Rest0)); K -> Exts = Cookie0#setcookie.extensions, case skip_space(Rest0) of [$=|Rest1] -> {V, Q, Rest2} = parse_cookie_value(skip_space(Rest1)), Cookie1 = Cookie0#setcookie{extensions=[{K,V,Q}|Exts]}, parse_set_cookie_result(Cookie1, skip_space(Rest2)); [$;|Rest1] -> Cookie1 = Cookie0#setcookie{ extensions=[{K,undefined,false}|Exts] }, parse_set_cookie_options(Rest1, Cookie1); [$,|Rest1] -> Cookie1 = Cookie0#setcookie{ extensions=[{K,undefined,false}|Exts] }, {Cookie1, Rest1}; [] -> Cookie1 = Cookie0#setcookie{ extensions=[{K,undefined,false}|Exts] }, {Cookie1, []}; _ -> error end end. parse_set_cookie_domain([C|_]=Rest, []) when C < $A orelse C > $Z orelse C < $a orelse C > $z orelse C /= $. -> parse_cookie_value(Rest); parse_set_cookie_domain([C|_]=Rest, [_|_]=Acc) when C < $0 orelse C > $9 orelse C < $A orelse C > $Z orelse C < $a orelse C > $z orelse C /= $. orelse C /= $- -> {lists:reverse(Acc), false, Rest}; parse_set_cookie_domain([], Acc) -> {lists:reverse(Acc), false, []}; parse_set_cookie_domain([C|T], Acc) -> parse_set_cookie_domain(T, [C|Acc]). parse_set_cookie_maxage([C|_]=Rest, []) when C < $1 orelse C > $9 -> parse_cookie_value(Rest); parse_set_cookie_maxage([C|_]=Rest, [_|_]=Acc) when C < $0 orelse C > $9 -> {lists:reverse(Acc), false, Rest}; parse_set_cookie_maxage([], Acc) -> {lists:reverse(Acc), false, []}; parse_set_cookie_maxage([C|T], Acc) -> parse_set_cookie_maxage(T, [C|Acc]). %% First of all, try to parse valid rfc1123 date (faster), then use a regex %% (more permissive) parse_set_cookie_expires([D,A,Y,$,,$\s,D1,D2,SEP,M,O,N,SEP,Y1,Y2,Y3,Y4,$\s, H1,H2,$:,M1,M2,$:,S1,S2,$\s,Z1,Z2,Z3|Rest]) when SEP =:= $- orelse SEP =:= $\s -> {[D,A,Y,$,,$\s,D1,D2,SEP,M,O,N,SEP,Y1,Y2,Y3,Y4,$\s, H1,H2,$:,M1,M2,$:,S1,S2,$\s,Z1,Z2,Z3], false, Rest}; parse_set_cookie_expires(Str) -> RE = "^(" "(?:[a-zA-Z]+,\s+)?" %% Week day "[0-9]+(?:\s|-)[a-zA-Z]+(?:\s|-)[0-9]+" %% DD Month YYYY "\s+[0-9]+:[0-9]+:[0-9]+" %% hh:mm:ss "(?:\s+[a-zA-Z]+)?" %% timezone ")" "(.*)$", case re:run(Str, RE, [{capture, all_but_first, list}, caseless]) of {match, [Date, Rest]} -> {Date, false, Rest}; nomatch -> parse_cookie_value(Str) end. parse_set_cookie_result(Cookie, [$;|Rest]) -> parse_set_cookie_options(Rest, Cookie); parse_set_cookie_result(Cookie, [$,|Rest]) -> {Cookie, Rest}; parse_set_cookie_result(Cookie, []) -> {Cookie, []}; parse_set_cookie_result(_, _) -> error. %% parse_cookie(Str) -> parse_cookie(Str, []). parse_cookie([], Cookies) -> lists:reverse(Cookies); parse_cookie(Str, Cookies) -> {Key, Rest0} = parse_cookie_key(skip_space(Str), []), case yaws:to_lower(Key) of [] -> []; K -> case skip_space(Rest0) of [$=|Rest1] -> {V, Q, Rest2} = parse_cookie_value(skip_space(Rest1)), C = #cookie{key=K, value=V, quoted=Q}, case skip_space(Rest2) of [$;|Rest3] -> parse_cookie(Rest3, [C|Cookies]); [$,|Rest3] -> parse_cookie(Rest3, [C|Cookies]); [] -> parse_cookie([], [C|Cookies]); _ -> [] end; [$;|Rest1] -> parse_cookie(Rest1, [#cookie{key=K}|Cookies]); [$,|Rest1] -> parse_cookie(Rest1, [#cookie{key=K}|Cookies]); [] -> parse_cookie([], [#cookie{key=K}|Cookies]); _ -> [] end end. %% %% All CHAR except ('=' | ';' | ',' | SP | HT | CRLF | LF) parse_cookie_key([], Acc) -> {lists:reverse(Acc), []}; parse_cookie_key(T=[$=|_], Acc) -> {lists:reverse(Acc), T}; parse_cookie_key(T=[$;|_], Acc) -> {lists:reverse(Acc), T}; parse_cookie_key(T=[$,|_], Acc) -> {lists:reverse(Acc), T}; parse_cookie_key(T=[$\s|_], Acc) -> {lists:reverse(Acc), T}; parse_cookie_key(T=[$\t|_], Acc) -> {lists:reverse(Acc), T}; parse_cookie_key(T=[$\r,$\n|_], Acc) -> {lists:reverse(Acc), T}; parse_cookie_key(T=[$\n|_], Acc) -> {lists:reverse(Acc), T}; parse_cookie_key([C|T], Acc) -> parse_cookie_key(T, [C|Acc]). %% parse_cookie_value([$"|T]) -> parse_cookie_quoted(T,[]); parse_cookie_value(T) -> parse_cookie_value(T,[]). %% All CHAR except (';' | ',' | SP | HT | CRLF | LF) parse_cookie_value([],Acc) -> {lists:reverse(Acc), false, []}; parse_cookie_value(T=[$;|_], Acc) -> {lists:reverse(Acc), false, T}; parse_cookie_value(T=[$,|_], Acc) -> {lists:reverse(Acc), false, T}; parse_cookie_value(T=[$\s|_], Acc) -> {lists:reverse(Acc), false, T}; parse_cookie_value(T=[$\t|_], Acc) -> {lists:reverse(Acc), false, T}; parse_cookie_value(T=[$\r,$\n|_], Acc) -> {lists:reverse(Acc), false, T}; parse_cookie_value(T=[$\n|_], Acc) -> {lists:reverse(Acc), false, T}; parse_cookie_value([C|T], Acc) -> parse_cookie_value(T, [C|Acc]). %% All CHAR except ('"' | CTLs) but including LWS and escape DQUOTEs %% CTL = any US-ASCII control character (octets 0 - 31) and DEL (127) %% LWS = [CRLF] 1*( SP | HT ) parse_cookie_quoted([], Acc) -> {lists:reverse(Acc), true, []}; parse_cookie_quoted([$"|T], Acc) -> {lists:reverse(Acc), true, T}; parse_cookie_quoted([$\\,C|T], Acc) -> parse_cookie_quoted(T,[C,$\\|Acc]); parse_cookie_quoted([$\t|T], Acc) -> parse_cookie_quoted(T,[$\t|Acc]); parse_cookie_quoted([$\r,$\n,$\s|T], Acc) -> parse_cookie_quoted(T,[$\s,$\n,$\r|Acc]); parse_cookie_quoted([$\r,$\n,$\t|T], Acc) -> parse_cookie_quoted(T,[$\t,$\n,$\r|Acc]); parse_cookie_quoted([C|T], Acc) when C > 31 andalso C < 127 -> parse_cookie_quoted(T,[C|Acc]); parse_cookie_quoted(T, Acc) -> {lists:reverse(Acc), true, T}. %% format_set_cookie(C) when C#setcookie.value == undefined -> [C#setcookie.key|format_cookie_opts(C)]; format_set_cookie(C) when C#setcookie.quoted -> [C#setcookie.key,$=,$",C#setcookie.value,$"|format_cookie_opts(C)]; format_set_cookie(C) -> [C#setcookie.key,$=,C#setcookie.value|format_cookie_opts(C)]. %% format_cookie([Cookie]) -> format_cookie(Cookie); format_cookie([Cookie|Rest]) -> [format_cookie(Cookie),$;,$\s|format_cookie(Rest)]; format_cookie(#cookie{key=Key, value=undefined}) -> Key; format_cookie(#cookie{key=Key, value=Value, quoted=true}) -> [Key,$=,$",Value,$"]; format_cookie(#cookie{key=Key, value=Value, quoted=false}) -> [Key,$=,Value]. %% format_cookie_opts(C=#setcookie{}) -> [ add_opt("Domain", C#setcookie.domain, false), add_opt("Max-Age", C#setcookie.max_age, false), add_opt("Expires", C#setcookie.expires, false), add_opt("Path", C#setcookie.path, false), add_opt("Secure", C#setcookie.secure, false), add_opt("HttpOnly", C#setcookie.http_only, false) ] ++ [add_opt(K,V,Q) || {K,V,Q} <- C#setcookie.extensions]. add_opt(_, undefined, _) -> []; add_opt(_, false, _) -> []; add_opt(Key, true, _) -> [$;,$\s,Key]; add_opt(Key, Opt, true) -> [$;,$\s,Key,$=,$",Opt,$"]; add_opt(Key, Opt, false) -> [$;,$\s,Key,$=,Opt]. %% skip_space([]) -> []; skip_space([$\s|T]) -> skip_space(T); skip_space([$\t|T]) -> skip_space(T); skip_space([$\r,$\n|T]) -> skip_space(T); skip_space([$\n|T]) -> skip_space(T); skip_space(T) -> T. %% getvar(ARG,Key) when is_atom(Key) -> getvar(ARG, atom_to_list(Key)); getvar(ARG,Key) -> filter_parse(Key, yaws_api:parse_query(ARG), yaws_api:parse_post(ARG)). queryvar(ARG,Key) when is_atom(Key) -> queryvar(ARG, atom_to_list(Key)); queryvar(ARG, Key) -> filter_parse(Key, yaws_api:parse_query(ARG), []). postvar(ARG, Key) when is_atom(Key) -> postvar(ARG, atom_to_list(Key)); postvar(ARG, Key) -> filter_parse(Key, [], yaws_api:parse_post(ARG)). filter_parse(Key, QueryParse, PostParse) -> Fun = fun({K,V}) -> (Key == K andalso V /= undefined) end, Values = lists:filter(Fun, QueryParse) ++ lists:filter(Fun, PostParse), case Values of [] -> undefined; [{_, V}] -> {ok,V}; %% Multivalued case - return list of values _ -> list_to_tuple(lists:map(fun({_,V}) -> V end, Values)) end. binding(Key) -> case get({binding, Key}) of undefined -> erlang:error({unknown_binding, Key}); Value -> Value end. binding_exists(Key) -> case get({binding, Key}) of undefined -> false; _ -> true end. %% Return the parsed url that the client requested. request_url(ARG) -> SC = get(sc), Headers = ARG#arg.headers, {abs_path, Path} = (ARG#arg.req)#http_request.path, DecPath = url_decode(Path), {P,Q} = yaws:split_at(DecPath, $?), #url{scheme = case SC#sconf.ssl of undefined -> "http"; _ -> "https" end, host = case Headers#headers.host of undefined -> yaws:upto_char($:, SC#sconf.servername); HostHdr -> yaws:upto_char($:, HostHdr) end, port = case {SC#sconf.ssl, SC#sconf.port} of {_, 80} -> undefined; {_, 443} -> undefined; {_, Port} -> Port end, path = P, querypart = Q}. %% remove sick characters sanitize_file_name(".." ++ T) -> sanitize_file_name([$.|T]); sanitize_file_name([H|T]) -> case lists:member(H, " &;'`{}!\\?<>\"()$") of true -> sanitize_file_name(T); false -> [H|sanitize_file_name(T)] end; sanitize_file_name([]) -> []. %% to be used in embedded mode, make it possible %% to pass a config to yaws from another data source %% than /etc/yaws/yaws.conf, for example from a database %% this code is also called by the server -h hup code setconf(GC0, Groups0) -> setconf(GC0, Groups0, true). setconf(GC0, Groups0, CheckCertsChanged) -> case CheckCertsChanged of true -> CertCheck = gen_server:call(yaws_server, check_certs, infinity), case lists:member(yes, CertCheck) of true -> application:stop(ssl), application:start(ssl); false -> ok end; false -> ok end, {GC, Groups1} = yaws_config:verify_upgrade_args(GC0, Groups0), Groups2 = lists:map(fun(X) -> yaws_config:add_yaws_auth(X) end, Groups1), {ok, OLDGC, OldGroups} = yaws_api:getconf(), case {yaws_config:can_hard_gc(GC, OLDGC), yaws_config:can_soft_setconf(GC, Groups2, OLDGC, OldGroups)} of {true, true} -> yaws_config:soft_setconf(GC, Groups2, OLDGC, OldGroups); {true, false} -> yaws_config:hard_setconf(GC, Groups2); _ -> {error, need_restart} end. %% return {ok, GC, Groups}. getconf() -> gen_server:call(yaws_server, getconf, infinity). %% return listen port number for the given sconf, useful if yaws is used in %% a test scenario where the configured port number is 0 (for requesting an %% ephemeral port) get_listen_port(SC) -> yaws_server:listen_port(SC). embedded_start_conf(DocRoot) when is_list(DocRoot) -> embedded_start_conf(DocRoot, []). embedded_start_conf(DocRoot, SL) when is_list(DocRoot), is_list(SL) -> embedded_start_conf(DocRoot, SL, []). embedded_start_conf(DocRoot, SL, GL) when is_list(DocRoot), is_list(SL), is_list(GL) -> embedded_start_conf(DocRoot, SL, GL, "default"). embedded_start_conf(DocRoot, SL, GL, Id) when is_list(DocRoot), is_list(SL), is_list(GL) -> case application:load(yaws) of ok -> ok; {error, {already_loaded,yaws}} -> ok; _ -> exit("cannot load yaws") end, ok = application:set_env(yaws, embedded, true), ok = application:set_env(yaws, id, Id), ChildSpecs = yaws_sup:child_specs(), GC = yaws:create_gconf(GL, Id), SCList = case SL of [] -> [[]]; [Cnf|_] when is_tuple(Cnf) -> [[yaws:create_sconf(DocRoot, SL)]]; [Cnf|_] when is_list(Cnf) -> [[yaws:create_sconf(DocRoot, SLItem)] || SLItem <- SL] end, SoapChild = yaws_config:add_yaws_soap_srv(GC, false), %% In case a server is started before any configuration has been set, %% this makes it possible to get hold of the 'pending' configuration. %% (see for example the start of the yaws_session_server) ok = application:set_env(yaws, embedded_conf, [{sclist,SCList},{gc,GC}]), yaws:mkdir(yaws:id_dir(Id)), {ok, SCList, GC, ChildSpecs ++ SoapChild}. %% Function which is invoked typically from an index.yaws file dir_listing(Arg) -> dir_listing(Arg, "."). dir_listing(Arg, RelDir) -> %% .yaws.auth Dir0 = filename:dirname(Arg#arg.fullpath), Dir = case RelDir of "." -> Dir0; _ -> filename:join([Dir0, RelDir]) end, Req = Arg#arg.req, case file:list_dir(Dir) of {ok, Data0} -> Data = Data0 -- [".yaws.auth", "index.yaws"], yaws_ls:list_directory(Arg, Arg#arg.clisock, Data, Dir, Req, false), ok; _Err -> %% Just ignore errors ??, the programmer has to %% make sure it's a valid path here ok end. %% Returns #redir_self{} record redirect_self(A) -> SC = get(sc), {Port, PortStr} = case {SC#sconf.rmethod, SC#sconf.ssl, SC#sconf.port} of {"https", _, 443} -> {443, ""}; {"http", _, 80} -> {80, ""}; {_, undefined, 80} -> {80, ""}; {_, undefined, Port2} -> {port, [$:|integer_to_list(Port2)]}; {_, _SSL, 443} -> {443, ""}; {_, _SSL, Port2} -> {Port2, [$:|integer_to_list(Port2)]} end, H = A#arg.headers, Host0 = yaws:redirect_host(get(sc), H#headers.host), %% redirect host contains the port number - for mysterious reasons Host = case string:tokens(Host0, ":") of [H0, _] -> H0; [H1] -> H1 end, {Scheme, SchemeStr} = case {SC#sconf.ssl,SC#sconf.rmethod} of {_, Method} when is_list(Method) -> {list_to_atom(Method), Method++"://"}; {undefined,_} -> {http, "http://"}; {_SSl,_} -> {https, "https://"} end, #redir_self{host = Host, scheme = Scheme, scheme_str = SchemeStr, port = Port, port_str = PortStr}. yaws-2.0.2/src/yaws_rss.erl0000664000175000017500000004526012605311412012570 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_rss.erl %%% Created : 15 Dec 2004 by Torbjorn Tornkvist %%% %%% @doc A Yaws RSS feed interface. %%% %%% @author Torbjorn Tornkvist %%% @end %%% %%% $Id$ %%%---------------------------------------------------------------------- -module(yaws_rss). -behaviour(gen_server). %% External exports -export([start/0, start_link/0, open/1, open/2, close/0, close/2, insert/5, insert/6, insert/7, retrieve/2]). -export([t_setup/0, t_exp/0, t_xopen/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -record(s, { open_apps = [], % activated applications expire = false, % false | days rm_exp = false, % remove expired items max=infinite, % maximum number of elements in DB days=7, % maximum number of days in DB counter}). % item counter -define(SERVER, ?MODULE). -define(DB, ?MODULE). -define(DB_FNAME, "yaws_rss.dets"). -define(ITEM(App, Tag, Counter, Item), {{App, Tag, Counter}, Item}). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). start() -> gen_server:start({local, ?SERVER}, ?MODULE, [], []). %%% %%% @spec open(App::atom()) -> %%% {ok, DB::db()} | {error, string()} %%% %%% @type db(). An opaque handle leading to an RSS database. %%% %%% @doc See {@link open/2} %%% @end open(App) -> open(App, []). %%% %%% @spec open(App::atom(), Opts::list()) -> %%% {ok, DB::db()} | {error, string()} %%% %%% @doc Open a RSS database. %%% Per default dets is used as database, %%% but by using the db_mod option it is %%% possible to use your own database.
%%% These are the options: %%%

%%% %%%
{db_mod, Module}
%%%
If specified, the following functions will be %%% called:
    %%%
  • Module:open(Opts)
  • %%%
  • Module:insert(App,Tag,Title,Link,Desc,Creator,GregSec)
  • %%%
  • Module:retrieve(App,Tag) -> {Title, Link, Desc, Creator, GregSecs}
  • %%%
  • Module:close(DbName)
%%% This means that the default DB won't be used, and %%% no expiration handling will be done. Only the producing of %%% XML will thus be done. Also, the whole Opts will be %%% passed un-interpreted to the other DB module.
%%% %%%
{db_dir, Dir}
%%%
Specifies the directory where the database will be created. %%% Default is: /tmp
%%% %%%
{expire, Expire}
%%%
Specifies what method to use to expire items. Possible values %%% are: false, days, meaning %%% never expire, expire after a number of days. %%% Default is to never expire items.
%%% %%%
{days, Number}
%%%
Specifies the number of days befor an item is expired. %%% Default is 7 days.
%%% %%%
{rm_exp, Bool}
%%%
Specifies if expired items should be removed from %%% the database. Default is to not remove any items.
%%% %%%
{max, Number}
%%%
Specifies the maximum number of items that should %%% be stored in the database. The default in infinite
%%%

%%%

If no database exist, a new one will be created. %%% The returned database handle is to be used with {@link close/1}.

%%% @end %%% open(App, Opts) -> %% This is called during read of yaws.conf during startup, so make sure this %% server is up and running before invoking it ok = wait_for_server(?SERVER), gen_server:call(?SERVER, {open, App, Opts}, infinity). %%% %%% @spec close() -> ok | {error, string()} %%% %%% @doc Close the RSS database. %%% @end close() -> gen_server:call(?SERVER, {close, ?DB}, infinity). %%% %%% @spec close(DbMod::atom(), DbName::atom()) -> %%% ok | {error, string()} %%% %%% @doc Close the user provided RSS database. %%% A call to; DbMod:close(DbName) will be made. %%% @end close(DBmod, DBname) -> gen_server:call(?SERVER, {close, DBmod, DBname}, infinity). %%% %%% @spec insert(App::atom(), Tag::atom(), Title::string(), %%% Link::string(), Desc::string()) -> %%% ok | {error, string()} %%% %%% @doc Insert an RSS item into the {App,Tag} RSS feed. %%% An application (App) can maintain several feeds each %%% one refered to with a symbolic name (Tag). %%% Link should be a URL pointing to the item. %%%

In case another database backend is used, the %%% Tag has the format: {DbModule, OpaqueTag} %%% where DbModule is the database backend module %%% to be called, and OpaqueTag the Tag that is %%% used in DbModule:insert(Tag, ...)

%%% @end %%% insert(App, Tag, Title, Link, Desc) -> insert(App, Tag, Title, Link, Desc, ""). %%% %%% @spec insert(App::atom(), Tag::atom(), Title::string(), %%% Link::string(), Desc::string(), %%% Creator::string()) -> %%% ok | {error, string()} %%% %%% @doc Works as {@link insert/5} but takes an extra argument %%% Creator which may contains an identification %%% of who created the item. %%% @end insert(App, Tag, Title, Link, Desc, Creator) -> GregSecs = calendar:datetime_to_gregorian_seconds({date(),time()}), insert(App, Tag, Title, Link, Desc, Creator, GregSecs). %%% %%% @spec insert(App::atom(), Tag::atom(), Title::string(), %%% Link::string(), Desc::string(), %%% Creator::string(), GregSecs::integer()) -> %%% ok | {error, string()} %%% %%% @doc Works as {@link insert/6} but takes an extra argument %%% GregSecs which is the creation time of the item %%% in Gregorian Seconds. %%% @end insert(App, Tag, Title, Link, Desc, Creator, GregSecs) -> Args = {App, Tag, Title, Link, Desc, Creator, GregSecs}, gen_server:call(?SERVER, {insert, Args}, infinity). %%% %%% @spec retrieve(App::atom(), Tag::atom()) -> %%% {ok, RSSContent::iolist()} |{error, string()} %%% %%% @type ioList(). A deep list of strings and/or binaries. %%% %%% @doc Retrieve the RSScontent (in XML and all...) %%% to be delivered to a RSS client. %%%

In case another database backend is used, the %%% Tag has the format: {DbModule, OpaqueTag} %%% where DbModule is the database backend module %%% to be called, and OpaqueTag the Tag that is %%% used in DbModule:retrieve(Tag) which must return %%% a list of tuples: {Title, Link, Desc, Creator, GregSecs}

%%% @end retrieve(App, Tag) -> gen_server:call(?SERVER, {retrieve, App, Tag}, infinity). %%%---------------------------------------------------------------------- %%% Callback functions from gen_server %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %%---------------------------------------------------------------------- init([]) -> {ok, #s{}}. %%---------------------------------------------------------------------- %% Func: handle_call/3 %% Returns: {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_call({open, App, Opts}, _From, State) -> {NewState, Res} = do_open_dir(State, App, Opts), {reply, Res, NewState}; %% handle_call({close, DB}, _From, State) -> dets:close(DB), {reply, ok, State}; %% handle_call({close, DBMod, DBname}, _From, State) -> catch apply(DBMod, close, [DBname]), {reply, ok, State}; %% handle_call({insert, Args}, _From, State) -> {NewState, Res} = do_insert(State, Args), {reply, Res, NewState}; %% handle_call({retrieve, App, Tag}, _From, State) -> {NewState, Res} = do_retrieve(State, App, Tag), {reply, Res, NewState}. %%---------------------------------------------------------------------- %% Func: handle_cast/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%---------------------------------------------------------------------- %% Func: handle_info/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_info(_Info, State) -> {noreply, State}. %%---------------------------------------------------------------------- %% Func: terminate/2 %% Purpose: Shutdown the server %% Returns: any (ignored by gen_server) %%---------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%---------------------------------------------------------------------- %% Func: code_change/3 %% Purpose: Handle upgrade %% Returns: new State data %%---------------------------------------------------------------------- code_change(_OldVsn, Data, _Extra) -> {ok, Data}. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- %%% %%% Check what database store that should be used. %%% Per default 'dets' is used. %%% do_open_dir(State, App, Opts) -> case get_db_mod(Opts, dets) of dets -> File = get_db_file(Opts), Expire = get_expire(Opts, #s.expire), Max = get_max(Opts, #s.max), Days = get_days(Opts, #s.days), RmExp = get_rm_exp(Opts, #s.rm_exp), case dets:is_dets_file(File) of false -> {State, {error, "not a proper dets file"}}; _ -> case catch dets:open_file(?DB, [{file, File}]) of {ok,DB} = Res -> {State#s{ open_apps = u_insert(App, State#s.open_apps), expire = Expire, days = Days, rm_exp = RmExp, max = Max, counter = init_counter(DB)}, Res}; {error, _Reason} -> {State, {error, "open dets file"}} end end; DBmod -> {State, catch apply(DBmod, open, Opts)} end. get_db_file(Opts) -> Dir = get_db_dir(Opts, "/tmp"), Dir ++ "/" ++ a2l(?DB) ++ ".dets". init_counter(DB) -> case dets:lookup(DB, counter) of [] -> dets:insert(DB, {counter, 0}), 0; [{counter,N}] -> N end. set_counter(DB, N) -> dets:insert(DB, {counter, N}). do_insert(State, {App, {DbMod,Tag}, Title, Link, Desc, Creator, GregSecs}) -> {State, catch apply(DbMod, insert, [App, Tag,Title,Link, Desc,Creator,GregSecs])}; do_insert(State, {App, Tag, Title, Link, Desc, Creator, GregSecs}) -> case lists:member(App, State#s.open_apps) of true -> Counter = if (State#s.max > 0) -> (State#s.counter + 1) rem State#s.max; true -> State#s.counter + 1 end, Item = {Title, Link, Desc, Creator, GregSecs}, Res = dets:insert(?DB, ?ITEM(App, Tag, Counter, Item)), set_counter(?DB, Counter), {State#s{counter = Counter}, Res}; false -> {State, {error, "no open DB"}} end. do_retrieve(State, App, {DbMod,Tag}) -> {State, catch apply(DbMod, retrieve, [App, Tag])}; do_retrieve(State, App, Tag) -> case lists:member(App, State#s.open_apps) of true -> F = fun(?ITEM(Xa, Xt, _Counter, Item), Acc) when Xa == App, Xt == Tag -> [Item|Acc]; (_, Acc) -> Acc end, Items = sort_items(expired(State, dets:foldl(F, [], ?DB))), Xml = to_xml(Items), {State, {ok, Xml}}; false -> {State, {error, "no open DB"}} end. -define(ONE_DAY, 86400). % 24*60*60 seconds -define(X(GregSecs), {Title, Link, Desc, Creator, GregSecs}). %%% Filter away expired items !! expired(State, List) when State#s.expire == days -> Gs = calendar:datetime_to_gregorian_seconds({date(),time()}), Old = Gs - (?ONE_DAY * State#s.days), F = fun(?X(GregSecs), Acc) when GregSecs > Old -> [?X(GregSecs) | Acc]; (_, Acc) -> Acc end, lists:foldl(F, [], List); expired(_State, List) -> List. -undef(X). %%% %%% Sort on creation date !! %%% Item = {Title, Link, Desc, Creator, GregSecs}, %%% sort_items(Is) -> lists:keysort(5,Is). to_xml([{Title, Link, Desc, Creator, GregSecs}|Tail]) -> Date = w3cdtf(GregSecs), [["\n", "", yaws_api:htmlize(Title), "\n", "", Link, "\n", "", Link, "\n", "", yaws_api:htmlize(Desc), "\n", "", Creator, "\n", "", Date, "\n", "\n"] | to_xml(Tail)]; to_xml([]) -> []. %%% %%% Create W3CDTF (http://www.w3.org/TR/NOTE-datetime) formatted date %%% w3cdtf(GregSecs) -> "YYYY-MM-DDThh:mm:ssTZD" %%% w3cdtf(GregSecs) -> Date = calendar:gregorian_seconds_to_datetime(GregSecs), {{Y, Mo, D},{H, Mi, S}} = Date, [UDate|_] = calendar:local_time_to_universal_time_dst( Date), {DiffD,{DiffH,DiffMi,_}}=calendar:time_difference( UDate,Date), w3cdtf_diff(Y, Mo, D, H, Mi, S, DiffD, DiffH, DiffMi). %%% w3cdtf's helper function w3cdtf_diff(Y, Mo, D, H, Mi, S, _DiffD, DiffH, DiffMi) when DiffH < 12, DiffH /= 0 -> i2l(Y) ++ "-" ++ add_zero(Mo) ++ "-" ++ add_zero(D) ++ "T" ++ add_zero(H) ++ ":" ++ add_zero(Mi) ++ ":" ++ add_zero(S) ++ "+" ++ add_zero(DiffH) ++ ":" ++ add_zero(DiffMi); w3cdtf_diff(Y, Mo, D, H, Mi, S, DiffD, DiffH, DiffMi) when DiffH > 12, DiffD == 0 -> i2l(Y) ++ "-" ++ add_zero(Mo) ++ "-" ++ add_zero(D) ++ "T" ++ add_zero(H) ++ ":" ++ add_zero(Mi) ++ ":" ++ add_zero(S) ++ "+" ++ add_zero(DiffH) ++ ":" ++ add_zero(DiffMi); w3cdtf_diff(Y, Mo, D, H, Mi, S, DiffD, DiffH, DiffMi) when DiffH > 12, DiffD /= 0, DiffMi /= 0 -> i2l(Y) ++ "-" ++ add_zero(Mo) ++ "-" ++ add_zero(D) ++ "T" ++ add_zero(H) ++ ":" ++ add_zero(Mi) ++ ":" ++ add_zero(S) ++ "-" ++ add_zero(23-DiffH) ++ ":" ++ add_zero(60-DiffMi); w3cdtf_diff(Y, Mo, D, H, Mi, S, DiffD, DiffH, DiffMi) when DiffH > 12, DiffD /= 0, DiffMi == 0 -> i2l(Y) ++ "-" ++ add_zero(Mo) ++ "-" ++ add_zero(D) ++ "T" ++ add_zero(H) ++ ":" ++ add_zero(Mi) ++ ":" ++ add_zero(S) ++ "-" ++ add_zero(24-DiffH) ++ ":" ++ add_zero(DiffMi); w3cdtf_diff(Y, Mo, D, H, Mi, S, _DiffD, DiffH, _DiffMi) when DiffH == 0 -> i2l(Y) ++ "-" ++ add_zero(Mo) ++ "-" ++ add_zero(D) ++ "T" ++ add_zero(H) ++ ":" ++ add_zero(Mi) ++ ":" ++ add_zero(S) ++ "Z". add_zero(I) when is_integer(I) -> add_zero(i2l(I)); add_zero([A]) -> [$0,A]; add_zero(L) when is_list(L) -> L. get_db_mod(Opts, Def) -> lkup(db_mod, Opts, Def). get_db_dir(Opts, Def) -> lkup(db_dir, Opts, Def). get_expire(Opts, Def) -> lkup(expire, Opts, Def). get_max(Opts, Def) -> lkup(max, Opts, Def). get_days(Opts, Def) -> lkup(days, Opts, Def). get_rm_exp(Opts, Def ) -> lkup(rm_exp, Opts, Def). lkup(Key, List, Def) -> case lists:keysearch(Key, 1, List) of {value,{_,Value}} -> Value; _ -> Def end. u_insert(H, [H|T]) -> T; u_insert(E, [H|T]) -> [H|u_insert(E,T)]; u_insert(E, []) -> [E]. i2l(I) when is_integer(I) -> integer_to_list(I). a2l(A) when is_atom(A) -> atom_to_list(A). t_setup() -> %%open([{db_file, "yaws_rss.dets"}, {max,7}]), insert(test,xml,"Normalizing XML, Part 2", "http://www.xml.com/pub/a/2002/12/04/normalizing.html", "In this second and final look at applying relational " "normalization techniques to W3C XML Schema data modeling, " "Will Provost discusses when not to normalize, the scope " "of uniqueness and the fourth and fifth normal forms."), insert(test,xml,"The .NET Schema Object Model", "http://www.xml.com/pub/a/2002/12/04/som.html", "Priya Lakshminarayanan describes in detail the use of " "the .NET Schema Object Model for programmatic manipulation " "of W3C XML Schemas."), insert(test,xml,"SVG's Past and Promising Future", "http://www.xml.com/pub/a/2002/12/04/svg.html", "In this month's SVG column, Antoine Quint looks back at " "SVG's journey through 2002 and looks forward to 2003."). t_exp() -> %%open([{db_file, "yaws_rss.dets"}, {expire,days}]), insert(test,xml,"Expired article", "http://www.xml.com/pub/a/2002/12/04/normalizing.html", "In this second and final look at applying relational " "normalization techniques to W3C XML Schema data modeling, " "Will Provost discusses when not to normalize, the scope " "of uniqueness and the fourth and fifth normal forms.", "tobbe", 63269561882). % 6/12-2004 t_xopen() -> open([{db_file, "yaws_rss.dets"}, {expire,days}, {days, 20}]). wait_for_server(Server) -> wait_for_server(Server, 20). wait_for_server(_Server, 0) -> {error, timeout}; wait_for_server(Server, N) -> case erlang:whereis(Server) of undefined -> receive after 500 -> ok end, wait_for_server(Server, N-1); _ -> ok end. yaws-2.0.2/src/yaws.erl0000664000175000017500000032147712605311412011710 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws.erl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 16 Jan 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws). -author('klacke@bluetail.com'). -include("../include/yaws.hrl"). -include("../include/yaws_api.hrl"). -include("yaws_appdeps.hrl"). -include("yaws_debug.hrl"). -include_lib("kernel/include/file.hrl"). -export([start/0, stop/0, hup/0, hup/1, restart/0, modules/0, load/0]). -export([start_embedded/1, start_embedded/2, start_embedded/3, start_embedded/4, add_server/2, create_gconf/2, create_sconf/2, setup_sconf/2]). -export([gconf_yaws_dir/1, gconf_trace/1, gconf_flags/1, gconf_logdir/1, gconf_ebin_dir/1, gconf_src_dir/1, gconf_runmods/1, gconf_keepalive_timeout/1, gconf_keepalive_maxuses/1, gconf_max_num_cached_files/1, gconf_max_num_cached_bytes/1, gconf_max_size_cached_file/1, gconf_max_connections/1, gconf_process_options/1, gconf_large_file_chunk_size/1, gconf_mnesia_dir/1, gconf_log_wrap_size/1, gconf_cache_refresh_secs/1, gconf_include_dir/1, gconf_phpexe/1, gconf_yaws/1, gconf_id/1, gconf_enable_soap/1, gconf_soap_srv_mods/1, gconf_ysession_mod/1, gconf_acceptor_pool_size/1, gconf_mime_types_info/1, gconf_nslookup_pref/1]). -export([sconf_port/1, sconf_flags/1, sconf_redirect_map/1, sconf_rhost/1, sconf_rmethod/1, sconf_docroot/1, sconf_xtra_docroots/1, sconf_listen/1, sconf_servername/1, sconf_serveralias/1, sconf_yaws/1, sconf_ets/1, sconf_ssl/1, sconf_authdirs/1, sconf_partial_post_size/1, sconf_appmods/1, sconf_expires/1, sconf_errormod_401/1, sconf_errormod_404/1, sconf_arg_rewrite_mode/1, sconf_logger_mod/1, sconf_opaque/1, sconf_start_mod/1, sconf_allowed_scripts/1, sconf_tilde_allowed_scripts/1, sconf_index_files/1, sconf_revproxy/1, sconf_spotions/1, sconf_extra_cgi_vars/1, sconf_stats/1, sconf_fcgi_app_server/1, sconf_php_handler/1, sconf_shaper/1, sconf_deflate_options/1, sconf_mime_types_info/1, sconf_dispatch_mod/1]). -export([new_auth/0, auth_dir/1, auth_dir/2, auth_docroot/1, auth_docroot/2, auth_files/1, auth_files/2, auth_realm/1, auth_realm/2, auth_type/1, auth_type/2, auth_headers/1, auth_headers/2, auth_users/1, auth_users/2, auth_acl/1, auth_acl/2, auth_mod/1, auth_mod/2, auth_outmod/1, auth_outmod/2, auth_pam/1, auth_pam/2]). -export([new_ssl/0, ssl_keyfile/1, ssl_keyfile/2, ssl_certfile/1, ssl_certfile/2, ssl_verify/1, ssl_verify/2, ssl_fail_if_no_peer_cert/1, ssl_fail_if_no_peer_cert/2, ssl_depth/1, ssl_depth/2, ssl_password/1, ssl_password/2, ssl_cacertfile/1, ssl_cacertfile/2, ssl_dhfile/1, ssl_dhfile/2, ssl_ciphers/1, ssl_ciphers/2, ssl_cachetimeout/1, ssl_cachetimeout/2, ssl_secure_renegotiate/1, ssl_secure_renegotiate/2, ssl_client_renegotiation/1, ssl_client_renegotiation/2, ssl_protocol_version/1, ssl_protocol_version/2, ssl_honor_cipher_order/1, ssl_honor_cipher_order/2]). -export([new_deflate/0, deflate_min_compress_size/1, deflate_min_compress_size/2, deflate_compression_level/1, deflate_compression_level/2, deflate_window_size/1, deflate_window_size/2, deflate_mem_level/1, deflate_mem_level/2, deflate_strategy/1, deflate_strategy/2, deflate_use_gzip_static/1, deflate_use_gzip_static/2, deflate_mime_types/1, deflate_mime_types/2]). -export([new_mime_types_info/0, mime_types_info_mime_types_file/1, mime_types_info_mime_types_file/2, mime_types_info_types/1, mime_types_info_types/2, mime_types_info_charsets/1, mime_types_info_charsets/2, mime_types_info_default_type/1, mime_types_info_default_type/2, mime_types_info_default_charset/1, mime_types_info_default_charset/2]). -export([first/2, elog/2, filesize/1, upto/2, to_string/1, to_list/1, integer_to_hex/1, hex_to_integer/1, string_to_hex/1, hex_to_string/1, is_modified_p/2, flag/3, dohup/1, is_ssl/1, address/0, is_space/1, setopts/3, eat_crnl/2, get_chunk_num/2, get_chunk_header/2, get_chunk/4, get_chunk_trailer/2, list_to_uue/1, uue_to_list/1, printversion/0, strip_spaces/1, strip_spaces/2, month/1, mk2/1, home/0, arg_rewrite/1, to_lowerchar/1, to_lower/1, funreverse/2, is_prefix/2, split_sep/2, join_sep/2, accepts_gzip/2, upto_char/2, deepmap/2, ticker/2, ticker/3, unique_triple/0, get_time_tuple/0, parse_qvalue/1, parse_auth/1]). -export([outh_set_status_code/1, outh_set_non_cacheable/1, outh_set_content_type/1, outh_set_content_encoding/1, outh_set_cookie/1, outh_set_static_headers/3, outh_set_static_headers/4, outh_set_304_headers/3, outh_set_dyn_headers/3, outh_set_connection/1, outh_set_content_length/1, outh_set_dcc/2, outh_set_transfer_encoding_off/0, outh_set_auth/1, outh_set_vary/1, outh_clear_headers/0, outh_fix_doclose/0, dcc/2]). -export([make_allow_header/0, make_allow_header/1, make_server_header/0, make_last_modified_header/1, make_location_header/1, make_etag_header/1, make_content_range_header/1, make_content_length_header/1, make_content_encoding_header/1, make_connection_close_header/1, make_transfer_encoding_chunked_header/1, make_www_authenticate_header/1, make_etag/1, make_content_type_header/1, make_date_header/0, make_vary_header/1]). -export([outh_get_status_code/0, outh_get_contlen/0, outh_get_act_contlen/0, outh_inc_act_contlen/1, outh_get_doclose/0, outh_get_chunked/0, outh_get_content_encoding/0, outh_get_content_encoding_header/0, outh_get_content_type/0, outh_get_vary_fields/0, outh_serialize/0]). -export([accumulate_header/1, headers_to_str/1, getuid/0, user_to_home/1, uid_to_name/1, exists/1, mkdir/1]). -export([tcp_connect/3, tcp_connect/4, ssl_connect/3, ssl_connect/4]). -export([do_recv/3, do_recv/4, cli_recv/3, gen_tcp_send/2, http_get_headers/2]). -export([sconf_to_srvstr/1, redirect_host/2, redirect_port/1, redirect_scheme_port/1, redirect_scheme/1, tmpdir/0, tmpdir/1, mktemp/1, split_at/2, insert_at/3, id_dir/1, ctl_file/1]). -export([parse_ipmask/1, match_ipmask/2]). -export([get_app_dir/0, get_ebin_dir/0, get_priv_dir/0, get_inc_dir/0]). %% Internal -export([local_time_as_gmt_string/1, universal_time_as_string/1, stringdate_to_datetime/1]). start() -> ok = start_app_deps(), application:start(yaws, permanent). stop() -> application:stop(yaws). %%% Quick and easy way of starting Yaws in embedded mode. No need for any %%% start-script switches and no dependencies to Yaws header files. Just call %%% start_embedded/N and you are in the air. start_embedded(DocRoot) -> start_embedded(DocRoot, []). start_embedded(DocRoot, SL) when is_list(DocRoot),is_list(SL) -> start_embedded(DocRoot, SL, []). start_embedded(DocRoot, SL, GL) when is_list(DocRoot),is_list(SL),is_list(GL) -> start_embedded(DocRoot, SL, GL, "default"). start_embedded(DocRoot, SL, GL, Id) when is_list(DocRoot), is_list(SL), is_list(GL) -> ok = start_app_deps(), {ok, SCList, GC, _} = yaws_api:embedded_start_conf(DocRoot, SL, GL, Id), ok = application:start(yaws, permanent), yaws_config:add_yaws_soap_srv(GC), yaws_api:setconf(GC, SCList), ok. add_server(DocRoot, SL) when is_list(DocRoot),is_list(SL) -> SC = create_sconf(DocRoot, SL), %% Change #auth in authdirs to {Dir, #auth} if needed Fun = fun (A = #auth{dir = [Dir]}, Acc) -> [{Dir, A}| Acc]; (A, Acc) -> [A| Acc] end, Authdirs = lists:foldr(Fun, [], SC#sconf.authdirs), SC1 = yaws_config:add_yaws_auth(SC#sconf{authdirs = Authdirs}), yaws_config:add_sconf(SC1). create_gconf(GL, Id) when is_list(GL) -> Debug = case application:get_env(yaws, debug) of undefined -> false; {ok, D} -> D end, setup_gconf(GL, yaws_config:make_default_gconf(Debug, Id)). create_sconf(DocRoot, SL) when is_list(DocRoot), is_list(SL) -> SC = yaws_config:make_default_sconf(DocRoot, lkup(port, SL, undefined)), setup_sconf(SL, SC). start_app_deps() -> Deps = split_sep(?YAWS_APPDEPS, $,), catch lists:foldl(fun(App0, Acc) -> App = list_to_existing_atom(App0), case application:start(App, permanent) of ok -> Acc; {error,{already_started,App}} -> Acc; Else -> throw(Else) end end, ok, Deps). %% Access functions for the GCONF and SCONF records. gconf_yaws_dir (#gconf{yaws_dir = X}) -> X. gconf_trace (#gconf{trace = X}) -> X. gconf_flags (#gconf{flags = X}) -> X. gconf_logdir (#gconf{logdir = X}) -> X. gconf_ebin_dir (#gconf{ebin_dir = X}) -> X. gconf_src_dir (#gconf{src_dir = X}) -> X. gconf_runmods (#gconf{runmods = X}) -> X. gconf_keepalive_timeout (#gconf{keepalive_timeout = X}) -> X. gconf_keepalive_maxuses (#gconf{keepalive_maxuses = X}) -> X. gconf_max_num_cached_files (#gconf{max_num_cached_files = X}) -> X. gconf_max_num_cached_bytes (#gconf{max_num_cached_bytes = X}) -> X. gconf_max_size_cached_file (#gconf{max_size_cached_file = X}) -> X. gconf_max_connections (#gconf{max_connections = X}) -> X. gconf_process_options (#gconf{process_options = X}) -> X. gconf_large_file_chunk_size(#gconf{large_file_chunk_size = X}) -> X. gconf_mnesia_dir (#gconf{mnesia_dir = X}) -> X. gconf_log_wrap_size (#gconf{log_wrap_size = X}) -> X. gconf_cache_refresh_secs (#gconf{cache_refresh_secs = X}) -> X. gconf_include_dir (#gconf{include_dir = X}) -> X. gconf_phpexe (#gconf{phpexe = X}) -> X. gconf_yaws (#gconf{yaws = X}) -> X. gconf_id (#gconf{id = X}) -> X. gconf_enable_soap (#gconf{enable_soap = X}) -> X. gconf_soap_srv_mods (#gconf{soap_srv_mods = X}) -> X. gconf_ysession_mod (#gconf{ysession_mod = X}) -> X. gconf_acceptor_pool_size (#gconf{acceptor_pool_size = X}) -> X. gconf_mime_types_info (#gconf{mime_types_info = X}) -> X. gconf_nslookup_pref (#gconf{nslookup_pref = X}) -> X. sconf_port (#sconf{port = X}) -> X. sconf_flags (#sconf{flags = X}) -> X. sconf_redirect_map (#sconf{redirect_map = X}) -> X. sconf_rhost (#sconf{rhost = X}) -> X. sconf_rmethod (#sconf{rmethod = X}) -> X. sconf_docroot (#sconf{docroot = X}) -> X. sconf_xtra_docroots (#sconf{xtra_docroots = X}) -> X. sconf_listen (#sconf{listen = X}) -> X. sconf_servername (#sconf{servername = X}) -> X. sconf_serveralias (#sconf{serveralias = X}) -> X. sconf_yaws (#sconf{yaws = X}) -> X. sconf_ets (#sconf{ets = X}) -> X. sconf_ssl (#sconf{ssl = X}) -> X. sconf_authdirs (#sconf{authdirs = X}) -> X. sconf_partial_post_size (#sconf{partial_post_size = X}) -> X. sconf_appmods (#sconf{appmods = X}) -> X. sconf_expires (#sconf{expires = X}) -> X. sconf_errormod_401 (#sconf{errormod_401 = X}) -> X. sconf_errormod_404 (#sconf{errormod_404 = X}) -> X. sconf_arg_rewrite_mode (#sconf{arg_rewrite_mod = X}) -> X. sconf_logger_mod (#sconf{logger_mod = X}) -> X. sconf_opaque (#sconf{opaque = X}) -> X. sconf_start_mod (#sconf{start_mod = X}) -> X. sconf_allowed_scripts (#sconf{allowed_scripts = X}) -> X. sconf_tilde_allowed_scripts(#sconf{tilde_allowed_scripts = X}) -> X. sconf_index_files (#sconf{index_files = X}) -> X. sconf_revproxy (#sconf{revproxy = X}) -> X. sconf_spotions (#sconf{soptions = X}) -> X. sconf_extra_cgi_vars (#sconf{extra_cgi_vars = X}) -> X. sconf_stats (#sconf{stats = X}) -> X. sconf_fcgi_app_server (#sconf{fcgi_app_server = X}) -> X. sconf_php_handler (#sconf{php_handler = X}) -> X. sconf_shaper (#sconf{shaper = X}) -> X. sconf_deflate_options (#sconf{deflate_options = X}) -> X. sconf_mime_types_info (#sconf{mime_types_info = X}) -> X. sconf_dispatch_mod (#sconf{dispatch_mod = X}) -> X. %% Access functions for the AUTH record. new_auth() -> #auth{}. auth_dir (#auth{dir = X}) -> X. auth_docroot(#auth{docroot = X}) -> X. auth_files (#auth{files = X}) -> X. auth_realm (#auth{realm = X}) -> X. auth_type (#auth{type = X}) -> X. auth_headers(#auth{headers = X}) -> X. auth_users (#auth{users = X}) -> X. auth_acl (#auth{acl = X}) -> X. auth_mod (#auth{mod = X}) -> X. auth_outmod (#auth{outmod = X}) -> X. auth_pam (#auth{pam = X}) -> X. auth_dir (A, Dir) -> A#auth{dir = Dir}. auth_docroot(A, DocRoot) -> A#auth{docroot = DocRoot}. auth_files (A, Files) -> A#auth{files = Files}. auth_realm (A, Realm) -> A#auth{realm = Realm}. auth_type (A, Type) -> A#auth{type = Type}. auth_headers(A, Headers) -> A#auth{headers = Headers}. auth_users (A, Users) -> A#auth{users = Users}. auth_acl (A, Acl) -> A#auth{acl = Acl}. auth_mod (A, Mod) -> A#auth{mod = Mod}. auth_outmod (A, Outmod) -> A#auth{outmod = Outmod}. auth_pam (A, Pam) -> A#auth{pam = Pam}. setup_authdirs(SL, DefaultAuthDirs) -> case [A || {auth, A} <- SL] of [] -> DefaultAuthDirs; As -> [setup_auth(A) || A <- As] end. setup_auth(#auth{}=Auth) -> Auth; setup_auth(AuthProps) -> Auth = #auth{}, #auth{dir = lkup(dir, AuthProps, Auth#auth.dir), docroot = lkup(docroot, AuthProps, Auth#auth.docroot), files = lkup(files, AuthProps, Auth#auth.files), realm = lkup(realm, AuthProps, Auth#auth.realm), type = lkup(type, AuthProps, Auth#auth.type), headers = lkup(headers, AuthProps, Auth#auth.headers), users = lkup(users, AuthProps, Auth#auth.users), acl = lkup(acl, AuthProps, Auth#auth.acl), mod = lkup(mod, AuthProps, Auth#auth.mod), outmod = lkup(outmod, AuthProps, Auth#auth.outmod), pam = lkup(pam, AuthProps, Auth#auth.pam)}. %% Access functions for the SSL record. new_ssl() -> #ssl{}. ssl_keyfile (#ssl{keyfile = X}) -> X. ssl_certfile (#ssl{certfile = X}) -> X. ssl_verify (#ssl{verify = X}) -> X. ssl_fail_if_no_peer_cert(#ssl{fail_if_no_peer_cert = X}) -> X. ssl_depth (#ssl{depth = X}) -> X. ssl_password (#ssl{password = X}) -> X. ssl_cacertfile (#ssl{cacertfile = X}) -> X. ssl_dhfile (#ssl{dhfile = X}) -> X. ssl_ciphers (#ssl{ciphers = X}) -> X. ssl_cachetimeout (#ssl{cachetimeout = X}) -> X. ssl_secure_renegotiate (#ssl{secure_renegotiate = X}) -> X. ssl_client_renegotiation(#ssl{client_renegotiation = X}) -> X. ssl_protocol_version (#ssl{protocol_version = X}) -> X. ssl_honor_cipher_order (#ssl{honor_cipher_order = X}) -> X. ssl_keyfile (S, File) -> S#ssl{keyfile = File}. ssl_certfile (S, File) -> S#ssl{certfile = File}. ssl_verify (S, Verify) -> S#ssl{verify = Verify}. ssl_fail_if_no_peer_cert(S, Bool) -> S#ssl{fail_if_no_peer_cert = Bool}. ssl_depth (S, Depth) -> S#ssl{depth = Depth}. ssl_password (S, Pass) -> S#ssl{password = Pass}. ssl_cacertfile (S, File) -> S#ssl{cacertfile = File}. ssl_dhfile (S, File) -> S#ssl{dhfile = File}. ssl_ciphers (S, Ciphers) -> S#ssl{ciphers = Ciphers}. ssl_cachetimeout (S, Timeout) -> S#ssl{cachetimeout = Timeout}. ssl_secure_renegotiate (S, Bool) -> S#ssl{secure_renegotiate = Bool}. ssl_protocol_version (S, Vsns) -> S#ssl{protocol_version = Vsns}. -ifdef(HAVE_SSL_HONOR_CIPHER_ORDER). ssl_honor_cipher_order (S, Bool) -> S#ssl{honor_cipher_order = Bool}. -else. ssl_honor_cipher_order (S, _) -> S. -endif. -ifdef(HAVE_SSL_CLIENT_RENEGOTIATION). ssl_client_renegotiation(S, Bool) -> S#ssl{client_renegotiation = Bool}. -else. ssl_client_renegotiation(S, _) -> S. -endif. setup_ssl(SL, DefaultSSL) -> case lkup(ssl, SL, undefined) of undefined -> DefaultSSL; SSL when is_record(SSL, ssl) -> SSL; SSLProps when is_list(SSLProps) -> SSL = #ssl{}, #ssl{keyfile = lkup(keyfile, SSLProps, SSL#ssl.keyfile), certfile = lkup(certfile, SSLProps, SSL#ssl.certfile), verify = lkup(verify, SSLProps, SSL#ssl.verify), fail_if_no_peer_cert = lkup(fail_if_no_peer_cert, SSLProps, SSL#ssl.fail_if_no_peer_cert), depth = lkup(depth, SSLProps, SSL#ssl.depth), password = lkup(password, SSLProps, SSL#ssl.password), cacertfile = lkup(cacertfile, SSLProps, SSL#ssl.cacertfile), dhfile = lkup(dhfile, SSLProps, SSL#ssl.dhfile), ciphers = lkup(ciphers, SSLProps, SSL#ssl.ciphers), cachetimeout = lkup(cachetimeout, SSLProps, SSL#ssl.cachetimeout), secure_renegotiate = lkup(secure_renegotiate, SSLProps, SSL#ssl.secure_renegotiate), client_renegotiation = lkup(client_renegotiation, SSLProps, SSL#ssl.client_renegotiation), honor_cipher_order = lkup(honor_cipher_order, SSLProps, SSL#ssl.honor_cipher_order), protocol_version = lkup(protocol_version, SSLProps, undefined)} end. %% Access functions for the DEFLATE record. new_deflate() -> #deflate{}. deflate_min_compress_size(#deflate{min_compress_size = X}) -> X. deflate_compression_level(#deflate{compression_level = X}) -> X. deflate_window_size (#deflate{window_size = X}) -> X. deflate_mem_level (#deflate{mem_level = X}) -> X. deflate_strategy (#deflate{strategy = X}) -> X. deflate_use_gzip_static (#deflate{use_gzip_static = X}) -> X. deflate_mime_types (#deflate{mime_types = X}) -> X. deflate_min_compress_size(D, Min) -> D#deflate{min_compress_size = Min}. deflate_compression_level(D, Level) -> D#deflate{compression_level = Level}. deflate_window_size (D, Size) -> D#deflate{window_size = Size}. deflate_mem_level (D, Level) -> D#deflate{mem_level = Level}. deflate_strategy (D, Strat) -> D#deflate{strategy = Strat}. deflate_use_gzip_static (D, Bool) -> D#deflate{use_gzip_static = Bool}. deflate_mime_types (D, Types) -> D#deflate{mime_types = Types}. setup_deflate(SL, DefaultDeflate) -> case lkup(deflate_options, SL, undefined) of undefined -> DefaultDeflate; D when is_record(D, deflate) -> D; DProps when is_list(DProps) -> D = #deflate{}, #deflate{min_compress_size = lkup(min_compress_size, DProps, D#deflate.min_compress_size), compression_level = lkup(compression_level, DProps, D#deflate.compression_level), window_size = lkup(window_size, DProps, D#deflate.window_size), mem_level = lkup(mem_level, DProps, D#deflate.mem_level), strategy = lkup(strategy, DProps, D#deflate.strategy), use_gzip_static = lkup(use_gzip_static, DProps, D#deflate.use_gzip_static), mime_types = lkup(mime_types, DProps, D#deflate.mime_types)} end. %% Access functions to MIME_TYPES_INFO record. new_mime_types_info() -> #mime_types_info{}. mime_types_info_mime_types_file(#mime_types_info{mime_types_file = X}) -> X. mime_types_info_types (#mime_types_info{types = X}) -> X. mime_types_info_charsets (#mime_types_info{charsets = X}) -> X. mime_types_info_default_type (#mime_types_info{default_type = X}) -> X. mime_types_info_default_charset(#mime_types_info{default_charset = X}) -> X. mime_types_info_mime_types_file(M, File) -> M#mime_types_info{mime_types_file = File}. mime_types_info_types(M, Types) -> M#mime_types_info{types = Types}. mime_types_info_charsets(M, Charsets) -> M#mime_types_info{charsets = Charsets}. mime_types_info_default_type(M, Type) -> M#mime_types_info{default_type = Type}. mime_types_info_default_charset(M, Charset) -> M#mime_types_info{default_charset = Charset}. setup_mime_types_info(SL, DefaultMTI) -> case lkup(mime_types_info, SL, undefined) of undefined -> DefaultMTI; M when is_record(M, mime_types_info) -> M; MProps when is_list(MProps) -> M = #mime_types_info{}, #mime_types_info{mime_types_file = lkup(mime_types_file, MProps, M#mime_types_info.mime_types_file), types = lkup(types, MProps, M#mime_types_info.types), charsets = lkup(charsets, MProps, M#mime_types_info.charsets), default_type = lkup(default_type, MProps, M#mime_types_info.default_type), default_charset = lkup(default_charset, MProps, M#mime_types_info.default_charset)} end. %% Setup global configuration setup_gconf([], GC) -> GC; setup_gconf(GL, GC) -> #gconf{yaws_dir = lkup(yaws_dir, GL, GC#gconf.yaws_dir), trace = lkup(trace, GL, GC#gconf.trace), flags = set_gc_flags(lkup(flags, GL, []), GC#gconf.flags), logdir = lkup(logdir, GL, GC#gconf.logdir), ebin_dir = lkup(ebin_dir, GL, GC#gconf.ebin_dir), src_dir = lkup(src_dir, GL, GC#gconf.src_dir), runmods = lkup(runmods, GL, GC#gconf.runmods), keepalive_timeout = lkup(keepalive_timeout, GL, GC#gconf.keepalive_timeout), keepalive_maxuses = lkup(keepalive_maxuses, GL, GC#gconf.keepalive_maxuses), max_num_cached_files = lkup(max_num_cached_files, GL, GC#gconf.max_num_cached_files), max_num_cached_bytes = lkup(max_num_cached_bytes, GL, GC#gconf.max_num_cached_bytes), max_size_cached_file = lkup(max_size_cached_file, GL, GC#gconf.max_size_cached_file), max_connections = lkup(max_connections, GL, GC#gconf.max_connections), process_options = lkup(process_options, GL, GC#gconf.process_options), large_file_chunk_size = lkup(large_file_chunk_size, GL, GC#gconf.large_file_chunk_size), mnesia_dir = lkup(mnesia_dir, GL, GC#gconf.mnesia_dir), log_wrap_size = lkup(log_wrap_size, GL, GC#gconf.log_wrap_size), cache_refresh_secs = lkup(cache_refresh_secs, GL, GC#gconf.cache_refresh_secs), include_dir = lkup(include_dir, GL, GC#gconf.include_dir), phpexe = lkup(phpexe, GL, GC#gconf.phpexe), yaws = lkup(yaws, GL, GC#gconf.yaws), id = lkup(id, GL, GC#gconf.id), enable_soap = lkup(enable_soap, GL, GC#gconf.enable_soap), soap_srv_mods = lkup(soap_srv_mods, GL, GC#gconf.soap_srv_mods), ysession_mod = lkup(ysession_mod, GL, GC#gconf.ysession_mod), acceptor_pool_size = lkup(acceptor_pool_size, GL, GC#gconf.acceptor_pool_size), mime_types_info = setup_mime_types_info( GL, GC#gconf.mime_types_info ), nslookup_pref = lkup(nslookup_pref, GL, GC#gconf.nslookup_pref) }. set_gc_flags([{tty_trace, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags,?GC_TTY_TRACE, Bool)); set_gc_flags([{debug, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags, ?GC_DEBUG, Bool)); set_gc_flags([{copy_errlog, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags, ?GC_COPY_ERRLOG, Bool)); set_gc_flags([{copy_error_log, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags, ?GC_COPY_ERRLOG, Bool)); set_gc_flags([{backwards_compat_parse, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags, ?GC_BACKWARDS_COMPAT_PARSE, Bool)); set_gc_flags([{log_resolve_hostname, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags, ?GC_LOG_RESOLVE_HOSTNAME, Bool)); set_gc_flags([{fail_on_bind_err, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags,?GC_FAIL_ON_BIND_ERR,Bool)); set_gc_flags([{pick_first_virthost_on_nomatch, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags, ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH,Bool)); set_gc_flags([{use_old_ssl, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags,?GC_USE_OLD_SSL,Bool)); set_gc_flags([{use_erlang_sendfile, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags,?GC_USE_ERLANG_SENDFILE,Bool)); set_gc_flags([{use_yaws_sendfile, Bool}|T], Flags) -> set_gc_flags(T, flag(Flags,?GC_USE_YAWS_SENDFILE,Bool)); set_gc_flags([_|T], Flags) -> set_gc_flags(T, Flags); set_gc_flags([], Flags) -> Flags. %% Setup vhost configuration setup_sconf(SL, SC) -> #sconf{port = lkup(port, SL, SC#sconf.port), flags = set_sc_flags(lkup(flags, SL, []), SC#sconf.flags), redirect_map = lkup(redirect_map, SL, SC#sconf.redirect_map), rhost = lkup(rhost, SL, SC#sconf.rhost), rmethod = lkup(rmethod, SL, SC#sconf.rmethod), docroot = lkup(docroot, SL, SC#sconf.docroot), xtra_docroots = lkup(xtra_docroots, SL, SC#sconf.xtra_docroots), listen = lkup(listen, SL, SC#sconf.listen), servername = lkup(servername, SL, SC#sconf.servername), serveralias = lkup(serveralias, SL, SC#sconf.serveralias), yaws = lkup(yaws, SL, SC#sconf.yaws), ets = lkup(ets, SL, SC#sconf.ets), ssl = setup_ssl(SL, SC#sconf.ssl), authdirs = setup_authdirs(SL, SC#sconf.authdirs), partial_post_size = lkup(partial_post_size, SL, SC#sconf.partial_post_size), appmods = lkup(appmods, SL, SC#sconf.appmods), expires = lkup(expires, SL, SC#sconf.expires), errormod_401 = lkup(errormod_401, SL, SC#sconf.errormod_401), errormod_404 = lkup(errormod_404, SL, SC#sconf.errormod_404), errormod_crash = lkup(errormod_crash, SL, SC#sconf.errormod_crash), arg_rewrite_mod = lkup(arg_rewrite_mod, SL, SC#sconf.arg_rewrite_mod), logger_mod = lkup(logger_mod, SL, SC#sconf.logger_mod), opaque = lkup(opaque, SL, SC#sconf.opaque), start_mod = lkup(start_mod, SL, SC#sconf.start_mod), allowed_scripts = lkup(allowed_scripts, SL, SC#sconf.allowed_scripts), tilde_allowed_scripts = lkup(tilde_allowed_scripts, SL, SC#sconf.tilde_allowed_scripts), index_files = lkup(index_files, SL, SC#sconf.index_files), revproxy = lkup(revproxy, SL, SC#sconf.revproxy), soptions = lkup(soptions, SL, SC#sconf.soptions), extra_cgi_vars = lkup(extra_cgi_vars, SL, SC#sconf.extra_cgi_vars), stats = lkup(stats, SL, SC#sconf.stats), fcgi_app_server = lkup(fcgi_app_server, SL, SC#sconf.fcgi_app_server), php_handler = lkup(php_handler, SL, SC#sconf.php_handler), shaper = lkup(shaper, SL, SC#sconf.shaper), deflate_options = setup_deflate(SL, SC#sconf.deflate_options), mime_types_info = setup_mime_types_info( SL, SC#sconf.mime_types_info ), dispatch_mod = lkup(dispatchmod, SL, SC#sconf.dispatch_mod) }. set_sc_flags([{access_log, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_ACCESS_LOG, Bool)); set_sc_flags([{auth_log, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_AUTH_LOG, Bool)); set_sc_flags([{add_port, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_ADD_PORT, Bool)); set_sc_flags([{statistics, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_STATISTICS, Bool)); set_sc_flags([{tilde_expand, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_TILDE_EXPAND, Bool)); set_sc_flags([{dir_listings, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_DIR_LISTINGS, Bool)); set_sc_flags([{deflate, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_DEFLATE, Bool)); set_sc_flags([{dir_all_zip, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_DIR_ALL_ZIP, Bool)); set_sc_flags([{dav, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_DAV, Bool)); set_sc_flags([{fcgi_trace_protocol, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_FCGI_TRACE_PROTOCOL, Bool)); set_sc_flags([{fcgi_log_app_error, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_FCGI_LOG_APP_ERROR, Bool)); set_sc_flags([{forward_proxy, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_FORWARD_PROXY, Bool)); set_sc_flags([{auth_skip_docroot, Bool}|T], Flags) -> set_sc_flags(T, flag(Flags, ?SC_AUTH_SKIP_DOCROOT, Bool)); set_sc_flags([_Unknown|T], Flags) -> error_logger:format("Unknown and unhandled flag ~p~n", [_Unknown]), set_sc_flags(T, Flags); set_sc_flags([], Flags) -> Flags. lkup(Key, List, Def) -> case lists:keyfind(Key, 1, List) of {_,Value} -> Value; _ -> Def end. hup() -> dohup(undefined). hup(Sock) -> spawn(fun() -> group_leader(whereis(user), self()), dohup(Sock) end). dohup(Sock) -> Env = yaws_sup:get_app_args(), Res = try yaws_config:load(Env) of {ok, Gconf, Sconfs} -> yaws_api:setconf(Gconf, Sconfs); Err -> Err catch _:X -> X end, gen_event:notify(yaws_event_manager, {yaws_hupped, Res}), yaws_log:rotate(Res), case Sock of undefined -> {yaws_hupped, Res}; _ -> gen_tcp:send(Sock, io_lib:format("hupped: ~p~n", [Res])), gen_tcp:close(Sock) end. %%% misc funcs first(_F, []) -> false; first(F, [H|T]) -> case F(H) of {ok, Val} -> {ok, Val, H}; ok -> {ok, ok, H}; _ -> first(F, T) end. elog(F, As) -> error_logger:format(F, As). filesize(Fname) -> case file:read_file_info(Fname) of {ok, FI} when FI#file_info.type == regular -> {ok, FI#file_info.size}; {ok, FI} -> {error, FI#file_info.type}; Err -> Err end. upto(_I, []) -> []; upto(0, _) -> " ...."; upto(_I, [0|_]) -> " ...."; upto(I, [H|T]) -> [H|upto(I-1, T)]. to_string(X) when is_float(X) -> io_lib:format("~.2.0f",[X]); to_string(X) when is_integer(X) -> erlang:integer_to_list(X); to_string(X) when is_atom(X) -> atom_to_list(X); to_string(X) -> lists:concat([X]). to_list(L) when is_list(L) -> L; to_list(A) when is_atom(A) -> atom_to_list(A). integer_to_hex(I) -> case catch erlang:integer_to_list(I, 16) of {'EXIT', _} -> old_integer_to_hex(I); Int -> Int end. old_integer_to_hex(I) when I < 10 -> integer_to_list(I); old_integer_to_hex(I) when I < 16 -> [I-10+$A]; old_integer_to_hex(I) when I >= 16 -> N = trunc(I/16), old_integer_to_hex(N) ++ old_integer_to_hex(I rem 16). hex_to_integer(Hex) -> erlang:list_to_integer(Hex, 16). string_to_hex(String) -> HEXC = fun (D) when D > 9 -> $a + D - 10; (D) -> $0 + D end, lists:foldr(fun(E, Acc) -> [HEXC(E div 16),HEXC(E rem 16)|Acc] end, [], String). hex_to_string(Hex) -> DEHEX = fun (H) when H >= $a -> H - $a + 10; (H) when H >= $A -> H - $A + 10; (H) -> H - $0 end, {String, _} = lists:foldr(fun (E, {Acc, nolow}) -> {Acc, DEHEX(E)}; (E, {Acc, LO}) -> {[DEHEX(E)*16+LO|Acc], nolow} end, {[], nolow}, Hex), String. universal_time_as_string() -> universal_time_as_string(calendar:universal_time()). universal_time_as_string(UTime) -> time_to_string(UTime, "GMT"). local_time_as_gmt_string(LocalTime) -> time_to_string(erlang:localtime_to_universaltime(LocalTime), "GMT"). time_to_string({{Year, Month, Day}, {Hour, Min, Sec}}, Zone) -> [day(Year, Month, Day), ", ", mk2(Day), " ", month(Month), " ", erlang:integer_to_list(Year), " ", mk2(Hour), ":", mk2(Min), ":", mk2(Sec), " ", Zone]. mk2(I) when I < 10 -> [$0 | erlang:integer_to_list(I)]; mk2(I) -> erlang:integer_to_list(I). day(Year, Month, Day) -> int_to_wd(calendar:day_of_the_week(Year, Month, Day)). int_to_wd(1) -> "Mon"; int_to_wd(2) -> "Tue"; int_to_wd(3) -> "Wed"; int_to_wd(4) -> "Thu"; int_to_wd(5) -> "Fri"; int_to_wd(6) -> "Sat"; int_to_wd(7) -> "Sun". month(1) -> "Jan"; month(2) -> "Feb"; month(3) -> "Mar"; month(4) -> "Apr"; month(5) -> "May"; month(6) -> "Jun"; month(7) -> "Jul"; month(8) -> "Aug"; month(9) -> "Sep"; month(10) -> "Oct"; month(11) -> "Nov"; month(12) -> "Dec". month_str_to_int("Jan") -> 1; month_str_to_int("Feb") -> 2; month_str_to_int("Mar") -> 3; month_str_to_int("Apr") -> 4; month_str_to_int("May") -> 5; month_str_to_int("Jun") -> 6; month_str_to_int("Jul") -> 7; month_str_to_int("Aug") -> 8; month_str_to_int("Sep") -> 9; month_str_to_int("Oct") -> 10; month_str_to_int("Nov") -> 11; month_str_to_int("Dec") -> 12. stringdate_to_datetime([$ |T]) -> stringdate_to_datetime(T); stringdate_to_datetime([_D1, _D2, _D3, $\,, $ |Tail]) -> stringdate_to_datetime1(Tail). stringdate_to_datetime1([A, B, $\s |T]) -> stringdate_to_datetime2(T, erlang:list_to_integer([A,B])); stringdate_to_datetime1([A, $\s |T]) -> stringdate_to_datetime2(T, erlang:list_to_integer([A])). stringdate_to_datetime2([M1, M2, M3, $\s , Y1, Y2, Y3, Y4, $\s, H1, H2, $:, Min1, Min2,$:, S1, S2,$\s ,$G, $M, $T|_], Day) -> {{erlang:list_to_integer([Y1,Y2,Y3,Y4]), month_str_to_int([M1, M2, M3]), Day}, {erlang:list_to_integer([H1, H2]), erlang:list_to_integer([Min1, Min2]), erlang:list_to_integer([S1, S2])}}. %% used by If-Modified-Since header code is_modified_p(FI, UTC_string) -> case catch stringdate_to_datetime(UTC_string) of {'EXIT', _ } -> true; UTC -> MtimeUTC = erlang:localtime_to_universaltime(FI#file_info.mtime), (MtimeUTC > UTC) end. ticker(Time, Msg) -> ticker(Time, self(), Msg). ticker(Time, To, Msg ) -> spawn_link(fun() -> process_flag(trap_exit, true), yaws_ticker:ticker(Time, To, Msg) end). address() -> Sc = get(sc), ?F("
~s Server at ~s
", [case Sc#sconf.yaws of undefined -> (get(gc))#gconf.yaws; Signature -> Signature end, Sc#sconf.servername]). is_space($\s) -> true; is_space($\r) -> true; is_space($\n) -> true; is_space($\t) -> true; is_space(_) -> false. strip_spaces(String) -> strip_spaces(String, both). strip_spaces(String, left) -> drop_spaces(String); strip_spaces(String, right) -> lists:reverse(drop_spaces(lists:reverse(String))); strip_spaces(String, both) -> strip_spaces(drop_spaces(String), right). drop_spaces([]) -> []; drop_spaces(YS=[X|XS]) -> case is_space(X) of true -> drop_spaces(XS); false -> YS end. %%% basic uuencode and decode functionality list_to_uue(L) -> list_to_uue(L, []). list_to_uue([], Out) -> lists:reverse([$\n,enc(0)|Out]); list_to_uue(L, Out) -> {L45, L1} = get_45(L), Encoded = encode_line(L45), list_to_uue(L1, lists:reverse(Encoded, Out)). uue_to_list(L) -> uue_to_list(L, []). uue_to_list([], Out) -> lists:reverse(Out); uue_to_list(L, Out) -> {Decoded, L1} = decode_line(L), uue_to_list(L1, lists:reverse(Decoded, Out)). encode_line(L) -> [enc(length(L))|encode_line1(L)]. encode_line1([C0, C1, C2|T]) -> Char1 = enc(C0 bsr 2), Char2 = enc((C0 bsl 4) band 8#60 bor (C1 bsr 4) band 8#17), Char3 = enc((C1 bsl 2) band 8#74 bor (C2 bsr 6) band 8#3), Char4 = enc(C2 band 8#77), [Char1,Char2,Char3,Char4|encode_line1(T)]; encode_line1([C1, C2]) -> encode_line1([C1, C2, 0]); encode_line1([C]) -> encode_line1([C,0,0]); encode_line1([]) -> [$\n]. decode_line([H|T]) -> case dec(H) of 0 -> {[], []}; Len -> decode_line(T, Len, []) end. decode_line([P0,P1,P2,P3|T], N, Out) when N >= 3-> Char1 = 16#FF band ((dec(P0) bsl 2) bor (dec(P1) bsr 4)), Char2 = 16#FF band ((dec(P1) bsl 4) bor (dec(P2) bsr 2)), Char3 = 16#FF band ((dec(P2) bsl 6) bor dec(P3)), decode_line(T, N-3, [Char3,Char2,Char1|Out]); decode_line([P0,P1,P2,_|T], 2, Out) -> Char1 = 16#FF band ((dec(P0) bsl 2) bor (dec(P1) bsr 4)), Char2 = 16#FF band ((dec(P1) bsl 4) bor (dec(P2) bsr 2)), {lists:reverse([Char2,Char1|Out]), tl(T)}; decode_line([P0,P1,_,_|T], 1, Out) -> Char1 = 16#FF band ((dec(P0) bsl 2) bor (dec(P1) bsr 4)), {lists:reverse([Char1|Out]), tl(T)}; decode_line(T, 0, Out) -> {lists:reverse(Out), tl(T)}. get_45(L) -> get_45(L, 45, []). get_45(L, 0, F) -> {lists:reverse(F), L}; get_45([], _N, L) -> {lists:reverse(L), []}; get_45([H|T], N, L) -> get_45(T, N-1, [H|L]). %% enc/1 is the basic 1 character encoding function to make a char printing %% dec/1 is the inverse enc(0) -> $`; enc(C) -> (C band 8#77) + $ . dec(Char) -> (Char - $ ) band 8#77. printversion() -> io:format("Yaws ~s~n", [yaws_generated:version()]), init:stop(). %% our default arg rewriter does of course nothing arg_rewrite(A) -> A. is_ssl(#sconf{ssl = undefined}) -> nossl; is_ssl(#sconf{ssl = S}) when is_record(S, ssl) -> ssl. to_lowerchar(C) when C >= $A, C =< $Z -> C+($a-$A); to_lowerchar(C) -> C. to_lower([]) -> []; to_lower([C|Cs]) when C >= $A, C =< $Z -> [C+($a-$A)|to_lower(Cs)]; to_lower([C|Cs]) -> [C|to_lower(Cs)]; to_lower(A) when is_atom(A) -> to_lower(atom_to_list(A)). funreverse(List, Fun) -> funreverse(List, Fun, []). funreverse([H|T], Fun, Ack) -> funreverse(T, Fun, [Fun(H)|Ack]); funreverse([], _Fun, Ack) -> Ack. %% is arg1 a prefix of arg2 is_prefix([H|T1], [H|T2]) -> is_prefix(T1, T2); is_prefix([], T) -> {true, T}; is_prefix(_,_) -> false. %% Split a string of words separated by Sep into a list of words and %% strip off white space. %% %% HTML semantics are used, such that empty words are omitted. split_sep(undefined, _Sep) -> []; split_sep(L, Sep) -> case drop_spaces(L) of [] -> []; [Sep|T] -> split_sep(T, Sep); [C|T] -> split_sep(T, Sep, [C], []) end. split_sep([], _Sep, AccL) -> lists:reverse(AccL); split_sep([Sep|T], Sep, AccL) -> split_sep(T, Sep, AccL); split_sep([C|T], Sep, AccL) -> split_sep(T, Sep, [C], AccL). split_sep([], _Sep, AccW, AccL) -> lists:reverse([lists:reverse(drop_spaces(AccW))|AccL]); split_sep([Sep|Tail], Sep, AccW, AccL) -> split_sep(drop_spaces(Tail), Sep, [lists:reverse(drop_spaces(AccW))|AccL]); split_sep([C|Tail], Sep, AccW, AccL) -> split_sep(Tail, Sep, [C|AccW], AccL). %% Join strings with separator. Same as string:join in later %% versions of Erlang. Separator is expected to be a list. join_sep([], Sep) when is_list(Sep) -> []; join_sep([H|T], Sep) -> H ++ lists:append([Sep ++ X || X <- T]). %% Provide a unique 3-tuple of positive integers. -ifdef(HAVE_ERLANG_NOW). unique_triple() -> now(). -else. unique_triple() -> {erlang:unique_integer([positive]), erlang:unique_integer([positive]), erlang:unique_integer([positive])}. -endif. %% Get a current time 3-tuple. -ifdef(HAVE_ERLANG_NOW). get_time_tuple() -> now(). -else. get_time_tuple() -> erlang:timestamp(). -endif. %% header parsing parse_qval(S) -> parse_qval([], S). parse_qval(A, ";q="++Q) -> {lists:reverse(A), parse_qvalue(Q)}; parse_qval(A, "") -> {lists:reverse(A), 1000}; parse_qval(A, [C|T]) -> parse_qval([C|A], T). parse_qvalue("0") -> 0; parse_qvalue("0.") -> 0; parse_qvalue("1") -> 1000; parse_qvalue("1.") -> 1000; parse_qvalue("1.0") -> 1000; parse_qvalue("1.00") -> 1000; parse_qvalue("1.000") -> 1000; parse_qvalue("0."++[D1]) -> three_digits_to_integer(D1,$0,$0); parse_qvalue("0."++[D1,D2]) -> three_digits_to_integer(D1,D2,$0); parse_qvalue("0."++[D1,D2,D3]) -> three_digits_to_integer(D1,D2,D3); parse_qvalue(_) -> 0. %% error three_digits_to_integer(D1, D2, D3) -> 100*(D1-$0)+10*(D2-$0)+D3-$0. %% Gzip encoding accepts_gzip(H, Mime) -> case [Val || {_,_,'Accept-Encoding',_,Val}<- H#headers.other] of [] -> false; [_|_]=AcceptEncoding0 -> AcceptEncoding = join_sep(AcceptEncoding0, ","), EncList = [parse_qval(X) || X <- split_sep(AcceptEncoding, $,)], case [Q || {"gzip",Q} <- EncList] ++ [Q || {"*",Q} <- EncList] of [] -> false; [Q|_] -> (Q > 100) %% just for fun and not has_buggy_gzip(H#headers.user_agent, Mime) end end. %%% Advice partly taken from Apache's documentation of `mod_deflate'. %% Only Netscape 4.06-4.08 is really broken. has_buggy_gzip("Mozilla/4.06"++_, _) -> true; has_buggy_gzip("Mozilla/4.07"++_, _) -> true; has_buggy_gzip("Mozilla/4.08"++_, _) -> true; %% Everything else handles at least HTML. has_buggy_gzip(_, "text/html") -> false; has_buggy_gzip(UserAgent, Mime) -> UA = parse_ua(UserAgent), in_ua(fun("Mozilla/4"++_) -> %% Netscape 4.x may choke on anything not HTML. case Mime of %% IE doesn't, but some versions are said to have issues %% with plugins. "application/pdf" -> true; _ -> not in_comment( fun("MSIE"++_) -> true; (_) -> false end, UA) end; ("w3m"++_) -> %% W3m does not decompress when saving. true; ("Opera") -> %% Opera 6 does not uncompress downloads. in_ua(fun("6."++_) -> true; (_) -> false end, UA); ("Opera/6."++_) -> true; (_) -> false end, UA). %%% Parsing of User-Agent header. %%% Yes, this looks a bit like overkill. tokenize_ua([], Acc) -> lists:reverse(Acc); tokenize_ua([$\\ , C|T], Acc) -> tokenize_ua(T, [C|Acc]); tokenize_ua([$(|T], Acc) -> tokenize_ua(T, [popen | Acc]); tokenize_ua([$)|T], Acc) -> tokenize_ua(T, [pclose | Acc]); tokenize_ua([C|T], Acc) -> tokenize_ua(T, [C|Acc]). parse_ua(Line) -> case catch parse_ua_l(tokenize_ua(Line, [])) of {'EXIT', _} -> []; Res -> Res end. parse_ua_l(Line) -> case drop_spaces(Line) of [] -> []; [popen|T] -> {Comment, Tail} = parse_comment(T), [Comment | parse_ua_l(Tail)]; [pclose|T] -> %% Error, ignore parse_ua_l(T); L -> {UA, Tail} = parse_ua1(L), [UA | parse_ua_l(Tail)] end. parse_comment(L) -> parse_comment(L, [], []). parse_comment([], _, _) -> %% Error {error, []}; parse_comment([pclose|T], CAcc, CsAcc) -> {{comment, lists:reverse([lists:reverse(CAcc)|CsAcc])}, T}; parse_comment([popen|T], CAcc, CsAcc) -> {Comment, Tail} = parse_comment(T), parse_comment(drop_spaces(Tail), [], [Comment, lists:reverse(CAcc)|CsAcc]); parse_comment([$;|T], CAcc, CsAcc) -> parse_comment(drop_spaces(T), [], [lists:reverse(CAcc)|CsAcc]); parse_comment([C|T], CAcc, CsAcc) -> parse_comment(T, [C|CAcc], CsAcc). parse_ua1(L) -> parse_ua1(L, []). parse_ua1([], Acc) -> {{ua,lists:reverse(Acc)}, []}; parse_ua1([popen|T], Acc) -> {{ua, lists:reverse(Acc)}, [popen|T]}; parse_ua1([pclose|T], _Acc) -> {error, T}; parse_ua1([$ |T], Acc) -> {{ua, lists:reverse(Acc)}, T}; parse_ua1([C|T], Acc) -> parse_ua1(T, [C|Acc]). in_ua(Pred, L) -> lists:any(fun({ua, UA}) -> Pred(UA); (_) -> false end, L). in_comment(_Pred, []) -> false; in_comment(Pred, [{comment, Cs}|T]) -> case in_comment_l(Pred, Cs) of true -> true; false -> in_comment(Pred, T) end; in_comment(Pred, [_|T]) -> in_comment(Pred, T). in_comment_l(Pred, Cs) -> lists:any(fun({comment, Cs1}) -> in_comment_l(Pred, Cs1); (error) -> false; (L) -> Pred(L) end, Cs). %% imperative out header management outh_set_status_code(Code) -> put(outh, (get(outh))#outh{status = Code}), ok. outh_set_non_cacheable(_Version) -> put(outh, (get(outh))#outh{cache_control = "Cache-Control: no-cache\r\n"}), ok. outh_set_content_type(Mime) -> put(outh, (get(outh))#outh{content_type = make_content_type_header(Mime)}), ok. outh_set_content_encoding(Encoding) -> ContentEncoding = case Encoding of identity -> undefined; deflate -> make_content_encoding_header(Encoding) end, put(outh, (get(outh))#outh{encoding = Encoding, content_encoding = ContentEncoding}), ok. outh_set_cookie(C) -> put(outh, (get(outh))#outh{set_cookie = ["Set-Cookie: ", C, "\r\n"]}), ok. outh_clear_headers() -> H = get(outh), put(outh, #outh{status = H#outh.status, doclose = true, chunked = false, connection = make_connection_close_header(true)}), ok. outh_set_static_headers(Req, UT, Headers) -> outh_set_static_headers(Req, UT, Headers, all). outh_set_static_headers(Req, UT, Headers, Range) -> H = get(outh), FIL = (UT#urltype.finfo)#file_info.size, {DoClose0, Chunked0} = dcc(Req, Headers), {DoDeflate, Length} = case Range of all -> case UT#urltype.deflate of DB when is_binary(DB) -> % cached %% Remove charset [Mime|_] = yaws:split_sep(UT#urltype.mime, $;), case accepts_gzip(Headers, Mime) of true -> {true, size(DB)}; false -> {false, FIL} end; undefined -> {false, FIL}; dynamic -> %% Remove charset [Mime|_] = yaws:split_sep(UT#urltype.mime, $;), case accepts_gzip(Headers, Mime) of true -> {true, undefined}; false -> {false, FIL} end end; {fromto, From, To, _} -> {false, To - From + 1} end, Encoding = case DoDeflate of true -> decide; false -> identity end, Chunked = Chunked0 and (Length == undefined), DoClose = if DoClose0 == true -> true; ((Length == undefined) and not Chunked) -> %% We cannot keep the connection alive, because the client %% has no way of knowing the end of the content data. true; DoClose0 == keep_alive -> keep_alive; true -> DoClose0 end, H2 = H#outh{ status = case Range of all -> 200; {fromto, _, _, _} -> 206 end, chunked = Chunked, encoding = Encoding, date = make_date_header(), server = make_server_header(), last_modified = make_last_modified_header(UT#urltype.finfo), etag = make_etag_header(UT#urltype.finfo), content_range = make_content_range_header(Range), content_length = make_content_length_header(Length), content_type = make_content_type_header(UT#urltype.mime), content_encoding = make_content_encoding_header(Encoding), transfer_encoding = make_transfer_encoding_chunked_header(Chunked), connection = make_connection_close_header(DoClose), doclose = DoClose, contlen = Length }, %% store finfo to set last_modified, expires and cache_control headers %% during #outh{} serialization. put(file_info, UT#urltype.finfo), put(outh, H2). outh_set_304_headers(Req, UT, Headers) -> H = get(outh), {DoClose, _Chunked} = dcc(Req, Headers), H2 = H#outh{ status = 304, chunked = false, date = make_date_header(), server = make_server_header(), last_modified = make_last_modified_header(UT#urltype.finfo), etag = make_etag_header(UT#urltype.finfo), content_length = make_content_length_header(0), connection = make_connection_close_header(DoClose), doclose = DoClose, contlen = 0 }, %% store finfo to set last_modified, expires and cache_control headers %% during #outh{} serialization. put(file_info, UT#urltype.finfo), put(outh, H2). outh_set_dyn_headers(Req, Headers, UT) -> H = get(outh), {DoClose, Chunked} = dcc(Req, Headers), H2 = H#outh{ status = 200, date = make_date_header(), server = make_server_header(), connection = make_connection_close_header(DoClose), content_type = make_content_type_header(UT#urltype.mime), doclose = DoClose, chunked = Chunked, transfer_encoding = make_transfer_encoding_chunked_header(Chunked)}, %% store finfo to set last_modified, expires and cache_control headers %% during #outh{} serialization. put(file_info, UT#urltype.finfo), put(outh, H2). outh_set_connection(What) -> H = get(outh), H2 = H#outh{connection = make_connection_close_header(What), doclose = What}, put(outh, H2), ok. outh_set_content_length(Int) -> H = get(outh), H2 = H#outh{ content_length = make_content_length_header(Int), contlen = Int }, put(outh, H2). outh_set_dcc(Req, Headers) -> H = get(outh), {DoClose, Chunked} = dcc(Req, Headers), H2 = H#outh{ connection = make_connection_close_header(DoClose), doclose = DoClose, chunked = Chunked, transfer_encoding = make_transfer_encoding_chunked_header(Chunked) }, put(outh, H2). %% can only turn if off, not on. %% if it allready is off, it's off because the cli headers forced us. outh_set_transfer_encoding_off() -> H = get(outh), H2 = H#outh{ chunked = false, transfer_encoding = make_transfer_encoding_chunked_header(false) }, put(outh, H2). outh_set_auth([]) -> ok; outh_set_auth(Headers) -> H = get(outh), H2 = case H#outh.www_authenticate of undefined -> H#outh{www_authenticate = Headers}; _ -> H#outh{www_authenticate = H#outh.www_authenticate ++ Headers} end, put(outh, H2). outh_set_vary(Fields) -> put(outh, (get(outh))#outh{vary = make_vary_header(Fields)}), ok. outh_fix_doclose() -> H = get(outh), if (H#outh.doclose /= true) andalso (H#outh.contlen==undefined) andalso (H#outh.chunked == false) -> put(outh, H#outh{doclose = true, connection = make_connection_close_header(true)}); true -> ok end. dcc(Req, Headers) -> H = get(outh), DoClose = case Req#http_request.version of _ when H#outh.exceedmaxuses == true -> true; %% too many keepalives {1, 0} -> case Headers#headers.connection of "close" -> true; "Keep-Alive" -> keep_alive; _ -> true end; {1, 1} -> Headers#headers.connection == "close"; {0,9} -> true end, Chunked = case Req#http_request.version of {1, 0} -> false; {1,1} -> true; {0,9} -> false end, {DoClose, Chunked}. %% %% The following all make_ function return an actual header string %% make_allow_header() -> make_allow_header([]). make_allow_header(Options) -> case Options of [] -> ["Allow: GET, POST, OPTIONS, HEAD\r\n"]; _ -> ["Allow: ", lists:foldl(fun(M, "") -> atom_to_list(M); (M, Acc) -> atom_to_list(M) ++ ", " ++ Acc end, "", lists:reverse(Options)), "\r\n"] end. make_server_header() -> Sc = get(sc), Signature = case Sc#sconf.yaws of undefined -> (get(gc))#gconf.yaws; S -> S end, ["Server: ", Signature, "\r\n"]. make_last_modified_header(FI) -> Then = FI#file_info.mtime, ["Last-Modified: ", local_time_as_gmt_string(Then), "\r\n"]. make_expires_header(all, FI) -> SC = get(sc), case lists:keyfind(all, 1, SC#sconf.expires) of {_, EType, TTL} -> make_expires_header(EType, TTL, FI); false -> {undefined, undefined} end; make_expires_header({Type,all}, FI) -> SC = get(sc), case lists:keyfind({Type,all}, 1, SC#sconf.expires) of {_, EType, TTL} -> make_expires_header(EType, TTL, FI); false -> make_expires_header(all, FI) end; make_expires_header({Type,SubType}, FI) -> SC = get(sc), case lists:keyfind({Type,SubType}, 1, SC#sconf.expires) of {_, EType, TTL} -> make_expires_header(EType, TTL, FI); false -> make_expires_header({Type,all}, FI) end; make_expires_header(MT0, FI) -> SC = get(sc), %% Use split_sep to remove charset case yaws:split_sep(MT0, $;) of [] -> {undefined, undefined}; [MT1|_] -> case lists:keyfind(MT1, 1, SC#sconf.expires) of {_, EType, TTL} -> make_expires_header(EType, TTL, FI); false -> case split_sep(MT1, $/) of [Type, SubType] -> make_expires_header({Type,SubType}, FI); false -> make_expires_header(all, FI) end end end. make_expires_header(always, _TTL, _FI) -> {["Expires: ", "Thu, 01 Jan 1970 00:00:00 GMT\r\n"], ["Cache-Control: ", "private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0\r\n"]}; make_expires_header(access, TTL, _FI) -> Secs = calendar:datetime_to_gregorian_seconds(erlang:universaltime()), ExpireTime = calendar:gregorian_seconds_to_datetime(Secs+TTL), {["Expires: ", universal_time_as_string(ExpireTime), "\r\n"], ["Cache-Control: ", "max-age=", erlang:integer_to_list(TTL), "\r\n"]}; make_expires_header(modify, TTL, FI) -> %% mtime is local here Secs1 = calendar:datetime_to_gregorian_seconds(FI#file_info.mtime), Secs2 = calendar:datetime_to_gregorian_seconds(erlang:localtime()), ExpireTime = calendar:gregorian_seconds_to_datetime(Secs1+TTL), MaxAge = erlang:max(0, TTL - (Secs2 - Secs1)), {["Expires: ", local_time_as_gmt_string(ExpireTime), "\r\n"], ["Cache-Control: ", "max-age=", erlang:integer_to_list(MaxAge), "\r\n"]}. make_location_header(Where) -> ["Location: ", Where, "\r\n"]. make_etag_header(FI) -> ETag = make_etag(FI), ["Etag: ", ETag, "\r\n"]. make_etag(FI) -> Stamp = {FI#file_info.size, FI#file_info.mtime}, ETag = integer_to_list(erlang:phash2(Stamp, 16#100000000), 19), lists:flatten([$", ETag, $"]). make_content_type_header(no_content_type) -> undefined; make_content_type_header(MimeType) -> ["Content-Type: ", MimeType, "\r\n"]. make_content_range_header(all) -> undefined; make_content_range_header({fromto, From, To, Tot}) -> ["Content-Range: bytes ", erlang:integer_to_list(From), $-, erlang:integer_to_list(To), $/, erlang:integer_to_list(Tot), $\r, $\n]. make_content_length_header(Size) when is_integer(Size) -> ["Content-Length: ", erlang:integer_to_list(Size), "\r\n"]; make_content_length_header(FI) when is_record(FI, file_info) -> Size = FI#file_info.size, ["Content-Length: ", erlang:integer_to_list(Size), "\r\n"]; make_content_length_header(_) -> undefined. make_content_encoding_header(deflate) -> "Content-Encoding: gzip\r\n"; make_content_encoding_header(_) -> undefined. make_connection_close_header(true) -> "Connection: close\r\n"; make_connection_close_header(false) -> undefined; make_connection_close_header(keep_alive) -> "Connection: Keep-Alive\r\n". make_transfer_encoding_chunked_header(true) -> "Transfer-Encoding: chunked\r\n"; make_transfer_encoding_chunked_header(false) -> undefined. make_www_authenticate_header({realm, Realm}) -> ["WWW-Authenticate: Basic realm=\"", Realm, ["\"\r\n"]]; make_www_authenticate_header(Method) -> ["WWW-Authenticate: ", Method, ["\r\n"]]. make_date_header() -> N = element(2, os:timestamp()), case get(date_header) of {_Str, Secs} when (Secs+10) < N -> H = ["Date: ", universal_time_as_string(), "\r\n"], put(date_header, {H, N}), H; {Str, _Secs} -> Str; undefined -> H = ["Date: ", universal_time_as_string(), "\r\n"], put(date_header, {H, N}), H end. make_vary_header(Fields) -> case lists:member("*", Fields) of true -> ["Vary: ", "*", "\r\n"]; false -> ["Vary: ", join_sep(Fields, ", "), "\r\n"] end. %% access functions into the outh record outh_get_status_code() -> (get(outh))#outh.status. outh_get_contlen() -> (get(outh))#outh.contlen. outh_get_act_contlen() -> (get(outh))#outh.act_contlen. outh_inc_act_contlen(Int) -> O = get(outh), L = case O#outh.act_contlen of undefined -> Int; Len -> Len+Int end, put(outh, O#outh{act_contlen = L}), L. outh_get_doclose() -> (get(outh))#outh.doclose. outh_get_chunked() -> (get(outh))#outh.chunked. outh_get_content_encoding() -> (get(outh))#outh.encoding. outh_get_content_encoding_header() -> (get(outh))#outh.content_encoding. outh_get_content_type() -> case (get(outh))#outh.content_type of undefined -> undefined; [_, Mime, _] -> Mime end. outh_get_vary_fields() -> case (get(outh))#outh.vary of undefined -> []; [_, Fields, _] -> split_sep(Fields, $,) end. outh_serialize() -> H = get(outh), Code = case H#outh.status of undefined -> 200; Int -> Int end, StatusLine = ["HTTP/1.1 ", erlang:integer_to_list(Code), " ", yaws_api:code_to_phrase(Code), "\r\n"], GC=get(gc), if ?gc_has_debug(GC) -> yaws_debug:check_headers(H); true -> ok end, ContentEnc = case H#outh.content_encoding of undefined -> make_content_encoding_header(H#outh.encoding); CE -> CE end, {Expires, CacheControl} = case erase(file_info) of undefined -> {H#outh.expires, H#outh.cache_control}; FI -> {E, CC} = case {H#outh.expires, H#outh.cache_control} of {undefined, undefined} -> CT = outh_get_content_type(), make_expires_header(CT, FI); _ -> {H#outh.expires, H#outh.cache_control} end, {E, CC} end, %% Add 'Accept-Encoding' in the 'Vary:' header if the compression is enabled %% or if the response is compressed _AND_ if the response has a non-empty %% body. Vary = case get(sc) of undefined -> undefined; SC -> case (?sc_has_deflate(SC) orelse H#outh.encoding == deflate) of true when H#outh.contlen /= undefined, H#outh.contlen /= 0; H#outh.act_contlen /= undefined, H#outh.act_contlen /= 0 -> Fields = outh_get_vary_fields(), Fun = fun("*") -> true; (F) -> (to_lower(F) == "accept-encoding") end, case lists:any(Fun, Fields) of true -> H#outh.vary; false -> make_vary_header(["Accept-Encoding"|Fields]) end; _ -> H#outh.vary end end, Headers = [noundef(H#outh.connection), noundef(H#outh.server), noundef(H#outh.location), noundef(H#outh.date), noundef(H#outh.allow), noundef(H#outh.last_modified), noundef(Expires), noundef(CacheControl), noundef(H#outh.etag), noundef(H#outh.content_range), noundef(H#outh.content_length), noundef(H#outh.content_type), noundef(ContentEnc), noundef(H#outh.set_cookie), noundef(H#outh.transfer_encoding), noundef(H#outh.www_authenticate), noundef(Vary), noundef(H#outh.other)], {StatusLine, Headers}. noundef(undefined) -> []; noundef(Str) -> Str. accumulate_header({X, erase}) when is_atom(X) -> erase_header(X); %% special headers accumulate_header({connection, What}) -> DC = case What of "close" -> true; _ -> false end, H = get(outh), put(outh, H#outh{connection = ["Connection: ", What, "\r\n"], doclose = DC}); accumulate_header({"Connection", What}) -> accumulate_header({connection, What}); accumulate_header({server, What}) -> put(outh, (get(outh))#outh{server = ["Server: ", What, "\r\n"]}); accumulate_header({"Server", What}) -> accumulate_header({server, What}); accumulate_header({location, What}) -> put(outh, (get(outh))#outh{location = ["Location: ", What, "\r\n"]}); accumulate_header({"Location", What}) -> accumulate_header({location, What}); accumulate_header({cache_control, What}) -> put(outh, (get(outh))#outh{cache_control = ["Cache-Control: ", What, "\r\n"]}); accumulate_header({"Cache-Control", What}) -> accumulate_header({cache_control, What}); accumulate_header({expires, What}) -> put(outh, (get(outh))#outh{expires = ["Expires: ", What, "\r\n"]}); accumulate_header({"Expires", What}) -> accumulate_header({expires, What}); accumulate_header({date, What}) -> put(outh, (get(outh))#outh{date = ["Date: ", What, "\r\n"]}); accumulate_header({"Date", What}) -> accumulate_header({date, What}); accumulate_header({allow, What}) -> put(outh, (get(outh))#outh{date = ["Allow: ", What, "\r\n"]}); accumulate_header({"Allow", What}) -> accumulate_header({allow, What}); accumulate_header({last_modified, What}) -> put(outh, (get(outh))#outh{last_modified = ["Last-Modified: ", What, "\r\n"]}); accumulate_header({"Last-Modified", What}) -> accumulate_header({last_modified, What}); accumulate_header({etag, What}) -> put(outh, (get(outh))#outh{etag = ["Etag: ", What, "\r\n"]}); accumulate_header({"Etag", What}) -> accumulate_header({etag, What}); accumulate_header({set_cookie, What}) -> O = get(outh), Old = case O#outh.set_cookie of undefined -> ""; X -> X end, put(outh, O#outh{set_cookie = ["Set-Cookie: ", What, "\r\n"|Old]}); accumulate_header({"Set-Cookie", What}) -> accumulate_header({set_cookie, What}); accumulate_header({content_range, What}) -> put(outh, (get(outh))#outh{content_range = ["Content-Range: ", What, "\r\n"]}); accumulate_header({"Content-Range", What}) -> accumulate_header({content_range, What}); accumulate_header({content_type, What}) -> put(outh, (get(outh))#outh{content_type = ["Content-Type: ", What, "\r\n"]}); accumulate_header({"Content-Type", What}) -> accumulate_header({content_type, What}); accumulate_header({content_encoding, What}) -> case What of "identity" -> put(outh, (get(outh))#outh{encoding = identity, content_encoding = undefined}); _ -> put(outh, (get(outh))#outh{encoding = deflate, content_encoding = ["Content-Encoding: ", What, "\r\n"]}) end; accumulate_header({"Content-Encoding", What}) -> accumulate_header({content_encoding, What}); accumulate_header({content_length, Len}) when is_integer(Len) -> H = get(outh), put(outh, H#outh{ chunked = false, transfer_encoding = undefined, contlen = Len, act_contlen = 0, content_length = make_content_length_header(Len)}); accumulate_header({"Content-Length", Len}) -> case Len of I when is_integer(I) -> accumulate_header({content_length, I}); L when is_list(L) -> accumulate_header({content_length, erlang:list_to_integer(L)}) end; accumulate_header({transfer_encoding, What}) -> put(outh, (get(outh))#outh{chunked = true, contlen = 0, transfer_encoding = ["Transfer-Encoding: ", What, "\r\n"]}); accumulate_header({"Transfer-Encoding", What}) -> accumulate_header({transfer_encoding, What}); accumulate_header({www_authenticate, What}) -> put(outh, (get(outh))#outh{www_authenticate = ["WWW-Authenticate: ", What, "\r\n"]}); accumulate_header({"WWW-Authenticate", What}) -> accumulate_header({www_authenticate, What}); accumulate_header({vary, What}) -> put(outh, (get(outh))#outh{vary = ["Vary: ", What, "\r\n"]}); accumulate_header({"Vary", What}) -> accumulate_header({vary, What}); %% non-special headers (which may be special in a future Yaws version) accumulate_header({Name, What}) when is_list(Name) -> H = get(outh), Old = case H#outh.other of undefined -> []; V -> V end, H2 = H#outh{other = [Name, ": ", What, "\r\n", Old]}, put(outh, H2); %% backwards compatible clause accumulate_header(Data) when is_list(Data) -> Str = lists:flatten(Data), accumulate_header(split_header(Str)). split_header(Str) -> split_header(Str, []). split_header([], A) -> {lists:reverse(A), ""}; split_header([$:, $ |W], A) -> {lists:reverse(A), W}; split_header([$:|W], A) -> {lists:reverse(A), W}; split_header([C|S], A) -> split_header(S, [C|A]). erase_header(connection) -> put(outh, (get(outh))#outh{connection=undefined, doclose=false}); erase_header(server) -> put(outh, (get(outh))#outh{server=undefined}); erase_header(cache_control) -> put(outh, (get(outh))#outh{cache_control=undefined}); erase_header(expires) -> put(outh, (get(outh))#outh{expires=undefined}); erase_header(date) -> put(outh, (get(outh))#outh{date=undefined}); erase_header(allow) -> put(outh, (get(outh))#outh{allow=undefined}); erase_header(last_modified) -> put(outh, (get(outh))#outh{last_modified=undefined}); erase_header(etag) -> put(outh, (get(outh))#outh{etag=undefined}); erase_header(set_cookie) -> put(outh, (get(outh))#outh{set_cookie=undefined}); erase_header(content_range) -> put(outh, (get(outh))#outh{content_range=undefined}); erase_header(content_length) -> put(outh, (get(outh))#outh{contlen=0, content_length=undefined}); erase_header(content_type) -> put(outh, (get(outh))#outh{content_type=undefined}); erase_header(content_encoding) -> put(outh, (get(outh))#outh{encoding=decide, content_encoding=undefined}); erase_header(transfer_encoding) -> put(outh, (get(outh))#outh{chunked = false, act_contlen = 0, transfer_encoding = undefined}); erase_header(www_authenticate) -> put(outh, (get(outh))#outh{www_authenticate=undefined}); erase_header(location) -> put(outh, (get(outh))#outh{location=undefined}); erase_header(vary) -> put(outh, (get(outh))#outh{vary=undefined}). getuid() -> case os:type() of {win32, _} -> {ok, "0"}; _ -> load_setuid_drv(), P = open_port({spawn, "setuid_drv g"},[]), receive {P, {data, "ok " ++ IntList}} -> {ok, IntList} end end. user_to_home(User) -> case os:type() of {win32, _} -> "."; _ -> load_setuid_drv(), P = open_port({spawn, "setuid_drv " ++ [$h|User]}, []), receive {P, {data, "ok " ++ Home}} -> Home end end. uid_to_name(Uid) -> load_setuid_drv(), P = open_port({spawn, "setuid_drv " ++ [$n|erlang:integer_to_list(Uid)]}, []), receive {P, {data, "ok " ++ Name}} -> Name end. load_setuid_drv() -> Path = filename:join(get_priv_dir(), "lib"), case erl_ddll:load_driver(Path, "setuid_drv") of ok -> ok; {error, Reason} -> error_logger:format("Failed to load setuid_drv (from ~p) : ~p", [Path, erl_ddll:format_error(Reason)]), exit(normal) end. exists(F) -> case file:open(F, [read, raw]) of {ok, Fd} -> file:close(Fd), ok; _ -> false end. mkdir(Path) -> [Hd|Parts] = filename:split(Path), mkdir([Hd], Parts). mkdir(Ack, []) -> ensure_exist(filename:join(Ack)); mkdir(Ack, [H|T]) -> ensure_exist(filename:join(Ack ++ [H])), mkdir(Ack ++ [H], T). ensure_exist(Path) -> case file:read_file_info(Path) of {ok, _} -> ok; _ -> case file:make_dir(Path) of ok -> ok; ERR -> error_logger:format("Failed to mkdir ~p: ~p~n", [Path, ERR]) end end. %% %% %% TCP/SSL connection with a configurable IPv4/IPv6 preference on NS lookup. %% %% tcp_connect(Host, Port, Options) -> tcp_connect(Host, Port, Options, infinity). tcp_connect(Host, Port, Options, Timeout) -> parse_ipaddr_and_connect(tcp, Host, Port, Options, Timeout). ssl_connect(Host, Port, Options) -> ssl_connect(Host, Port, Options, infinity). ssl_connect(Host, Port, Options, Timeout) -> parse_ipaddr_and_connect(ssl, Host, Port, Options, Timeout). parse_ipaddr_and_connect(Proto, IP, Port, Options, Timeout) when is_tuple(IP) -> %% The caller handled name resolution himself. filter_tcpoptions_and_connect(Proto, undefined, IP, Port, Options, Timeout); parse_ipaddr_and_connect(Proto, [$[ | Rest], Port, Options, Timeout) -> %% yaws_api:parse_url/1 keep the "[...]" enclosing an IPv6 address. %% Remove them now, and parse the address. IP = string:strip(Rest, right, $]), parse_ipaddr_and_connect(Proto, IP, Port, Options, Timeout); parse_ipaddr_and_connect(Proto, Host, Port, Options, Timeout) -> %% First, try to parse an IP address, because inet:getaddr/2 could %% return nxdomain if the family doesn't match the IP address %% format. case parse_strict_address(Host) of {ok, IP} -> filter_tcpoptions_and_connect(Proto, undefined, IP, Port, Options, Timeout); {error, einval} -> NsLookupPref = get_nslookup_pref(Options), filter_tcpoptions_and_connect(Proto, NsLookupPref, Host, Port, Options, Timeout) end. -ifdef(HAVE_INET_PARSE_STRICT_ADDRESS). parse_strict_address(Host) -> inet:parse_strict_address(Host). -else. parse_strict_address(Host) when is_list(Host) -> case inet_parse:ipv4strict_address(Host) of {ok,IP} -> {ok,IP}; _ -> inet_parse:ipv6strict_address(Host) end; parse_strict_address(_) -> {error, einval}. -endif. filter_tcpoptions_and_connect(Proto, NsLookupPref, Host, Port, Options, Timeout) -> %% Now that we have IP addresses, remove family from the TCP options, %% because calling gen_tcp:connect/3 with {127,0,0,1} and [inet6] %% would return {error, nxdomain otherwise}. OptionsWithoutFamily = lists:filter(fun (inet) -> false; (inet6) -> false; (_) -> true end, Options), resolve_and_connect(Proto, NsLookupPref, Host, Port, OptionsWithoutFamily, Timeout). resolve_and_connect(Proto, _, IP, Port, Options, Timeout) when is_tuple(IP) -> do_connect(Proto, IP, Port, Options, Timeout); resolve_and_connect(Proto, [Family | Rest], Host, Port, Options, Timeout) -> Result = case inet:getaddr(Host, Family) of {ok, IP} -> do_connect(Proto, IP, Port, Options, Timeout); R -> R end, case Result of {ok, Socket} -> {ok, Socket}; {error, _} when length(Rest) >= 1 -> %% If the connection fails here, ignore the error and %% continue with the next address family. resolve_and_connect(Proto, Rest, Host, Port, Options, Timeout); {error, Reason} -> %% This was the last IP address in the list, return the %% connection error. {error, Reason} end. do_connect(Proto, IP, Port, Options, Timeout) -> case Proto of tcp -> gen_tcp:connect(IP, Port, Options, Timeout); ssl -> ssl:connect(IP, Port, Options, Timeout) end. %% If the caller specified inet or inet6 in the TCP options, prefer %% this to the global nslookup_pref parameter. %% %% This can be used in processes which can't use get(gc) to get the %% global conf: if they are given the global conf, they can get %% nslookup_pref value and add it the TCP options. %% %% If neither TCP options specify the family, nor the global conf is %% accessible, use default value declared in #gconf definition. get_nslookup_pref(TcpOptions) -> get_nslookup_pref(TcpOptions, []). get_nslookup_pref([inet | Rest], Result) -> get_nslookup_pref(Rest, [inet | Result]); get_nslookup_pref([inet6 | Rest], Result) -> get_nslookup_pref(Rest, [inet6 | Result]); get_nslookup_pref([_ | Rest], Result) -> get_nslookup_pref(Rest, Result); get_nslookup_pref([], []) -> case get(gc) of undefined -> gconf_nslookup_pref(#gconf{}); GC -> gconf_nslookup_pref(GC) end; get_nslookup_pref([], Result) -> lists:reverse(Result). %% %% %% http/tcp send receive functions %% %% do_recv(Sock, Num, nossl) -> gen_tcp:recv(Sock, Num, (get(gc))#gconf.keepalive_timeout); do_recv(Sock, Num, ssl) -> ssl:recv(Sock, Num, (get(gc))#gconf.keepalive_timeout). do_recv(Sock, Num, nossl, Timeout) -> gen_tcp:recv(Sock, Num, Timeout); do_recv(Sock, Num, ssl, Timeout) -> ssl:recv(Sock, Num, Timeout). cli_recv(S, Num, SslBool) -> Res = do_recv(S, Num, SslBool), cli_recv_trace(yaws_trace:get_type(get(gc)), Res), Res. cli_recv_trace(undefined, _) -> ok; cli_recv_trace(Trace, Res) -> case Res of {ok, Val} when is_tuple(Val) -> yaws_trace:write(from_client, ?F("~p~n", [Val])); {error, What} -> yaws_trace:write(from_client, ?F("~p~n", [What])); {ok, http_eoh} -> ok; {ok, Val} when Trace == traffic -> yaws_trace:write(from_client, Val); _ -> ok end. gen_tcp_send(S, Data) -> SC = get(sc), Res = case SC of undefined -> case catch ssl:sockname(S) of {ok, _} -> ssl:send(S, Data); _ -> gen_tcp:send(S, Data) end; _ -> case SC#sconf.ssl of undefined -> gen_tcp:send(S, Data); _SSL -> ssl:send(S, Data) end end, case ?gc_has_debug((get(gc))) of false -> case Res of ok -> case SC of undefined -> ok; _ -> yaws_stats:sent(iolist_size(Data)) end, ok; _Err -> exit(normal) %% keep quiet end; true -> case Res of ok -> case SC of undefined -> ok; _ -> yaws_stats:sent(iolist_size(Data)) end, ?Debug("Sent ~p~n", [yaws_debug:nobin(Data)]), ok; Err -> {B2, Size} = strip(Data), yaws_debug:derror("Failed to send ~w bytes:~n~p " "on socket ~p: ~p~n~p~n", [Size, B2, S, Err, yaws_debug:nobin(Data)]), erlang:error(Err) end end. strip(Data) -> L = list_to_binary([Data]), case L of <> -> {binary_to_list(<>), size(L)}; _ -> {binary_to_list(L), size(L)} end. %% This is the api function %% return {Req, Headers} %% or closed http_get_headers(CliSock, SSL) -> do_http_get_headers(CliSock, SSL). headers_to_str(Headers) -> lists:map(fun(H) -> [H, "\r\n"] end, yaws_api:reformat_header(Headers)). setopts(Sock, Opts, nossl) -> ok = inet:setopts(Sock, Opts); setopts(Sock, Opts, ssl) -> ok = ssl:setopts(Sock, Opts). do_http_get_headers(CliSock, SSL) -> case http_recv_request(CliSock,SSL) of bad_request -> {#http_request{method=bad_request, version={0,9}}, #headers{}}; closed -> closed; R -> %% Http request received. Store the current time. it will be usefull %% to get the time taken to serve the request. put(request_start_time, os:timestamp()), case http_collect_headers(CliSock, R, #headers{}, SSL, 0) of {error, _}=Error -> Error; H -> {R, H} end end. http_recv_request(CliSock, SSL) -> setopts(CliSock, [{packet, http}, {packet_size, 16#4000}], SSL), case do_recv(CliSock, 0, SSL) of {ok, R} when is_record(R, http_request) -> R; {ok, R} when is_record(R, http_response) -> R; {_, {http_error, "\r\n"}} -> http_recv_request(CliSock, SSL); {_, {http_error, "\n"}} -> http_recv_request(CliSock,SSL); {_, {http_error, _}} -> bad_request; {error, closed} -> closed; {error, timeout} -> closed; _Other -> error_logger:format("Unhandled reply fr. do_recv() ~p~n", [_Other]), exit(normal) end. http_collect_headers(CliSock, Req, H, SSL, Count) when Count < 1000 -> setopts(CliSock, [{packet, httph}, {packet_size, 16#4000}], SSL), Recv = do_recv(CliSock, 0, SSL), case Recv of {ok, {http_header, _Num, 'Host', _, Host}} -> NewHostH = case H#headers.host of undefined -> H#headers{host = Host}; {Hosts} -> H#headers{host = {[Host | Hosts]}}; CurrentHost -> H#headers{host = {[Host, CurrentHost]}} end, http_collect_headers(CliSock, Req, NewHostH, SSL, Count+1); {ok, {http_header, _Num, 'Connection', _, Conn}} -> http_collect_headers(CliSock, Req, H#headers{connection = Conn},SSL, Count+1); {ok, {http_header, _Num, 'Accept', _, Accept}} -> http_collect_headers(CliSock, Req, H#headers{accept = Accept}, SSL, Count+1); {ok, {http_header, _Num, 'If-Modified-Since', _, X}} -> http_collect_headers(CliSock, Req, H#headers{if_modified_since = X},SSL, Count+1); {ok, {http_header, _Num, 'If-Match', _, X}} -> http_collect_headers(CliSock, Req, H#headers{if_match = X}, SSL, Count+1); {ok, {http_header, _Num, 'If-None-Match', _, X}} -> http_collect_headers(CliSock, Req, H#headers{if_none_match = X},SSL, Count+1); {ok, {http_header, _Num, 'If-Range', _, X}} -> http_collect_headers(CliSock, Req, H#headers{if_range = X}, SSL, Count+1); {ok, {http_header, _Num, 'If-Unmodified-Since', _, X}} -> http_collect_headers(CliSock, Req, H#headers{if_unmodified_since = X},SSL, Count+1); {ok, {http_header, _Num, 'Range', _, X}} -> http_collect_headers(CliSock, Req, H#headers{range = X}, SSL, Count+1); {ok, {http_header, _Num, 'Referer',_, X}} -> http_collect_headers(CliSock, Req, H#headers{referer = X}, SSL, Count+1); {ok, {http_header, _Num, 'User-Agent', _, X}} -> http_collect_headers(CliSock, Req, H#headers{user_agent = X}, SSL, Count+1); {ok, {http_header, _Num, 'Accept-Ranges', _, X}} -> http_collect_headers(CliSock, Req, H#headers{accept_ranges = X},SSL, Count+1); {ok, {http_header, _Num, 'Cookie', _, X}} -> http_collect_headers(CliSock, Req, H#headers{cookie = [X|H#headers.cookie]}, SSL, Count+1); {ok, {http_header, _Num, 'Keep-Alive', _, X}} -> http_collect_headers(CliSock, Req, H#headers{keep_alive = X}, SSL, Count+1); {ok, {http_header, _Num, 'Content-Length', _, X}} -> http_collect_headers(CliSock, Req, H#headers{content_length = X},SSL, Count+1); {ok, {http_header, _Num, 'Content-Type', _, X}} -> http_collect_headers(CliSock, Req, H#headers{content_type = X},SSL, Count+1); {ok, {http_header, _Num, 'Content-Encoding', _, X}} -> http_collect_headers(CliSock, Req, H#headers{content_encoding = X},SSL, Count+1); {ok, {http_header, _Num, 'Transfer-Encoding', _, X}} -> http_collect_headers(CliSock, Req, H#headers{transfer_encoding=X},SSL, Count+1); {ok, {http_header, _Num, 'Location', _, X}} -> http_collect_headers(CliSock, Req, H#headers{location=X}, SSL, Count+1); {ok, {http_header, _Num, 'Authorization', _, X}} -> http_collect_headers(CliSock, Req, H#headers{authorization = parse_auth(X)}, SSL, Count+1); {ok, {http_header, _Num, 'X-Forwarded-For', _, X}} -> case H#headers.x_forwarded_for of undefined -> http_collect_headers(CliSock, Req, H#headers{x_forwarded_for=X}, SSL, Count+1); PrevXF -> NewXF = join_sep([PrevXF,X], ", "), http_collect_headers(CliSock, Req, H#headers{x_forwarded_for=NewXF}, SSL, Count+1) end; {ok, http_eoh} -> H; %% these are here to be a little forgiving to %% bad (typically test script) clients {_, {http_error, "\r\n"}} -> http_collect_headers(CliSock, Req, H,SSL, Count+1); {_, {http_error, "\n"}} -> http_collect_headers(CliSock, Req, H,SSL, Count+1); %% auxiliary headers we don't have builtin support for {ok, X} -> ?Debug("OTHER header ~p~n", [X]), http_collect_headers(CliSock, Req, H#headers{other=[X|H#headers.other]}, SSL, Count+1); _Err -> exit(normal) end; http_collect_headers(_CliSock, Req, _H, _SSL, _Count) -> {error, {too_many_headers, Req}}. parse_auth(Orig = "Basic " ++ Auth64) -> case decode_base64(Auth64) of {error, _Err} -> {undefined, undefined, Orig}; Auth -> case string:tokens(Auth, ":") of [User, Pass] -> {User, Pass, Orig}; _ -> {undefined, undefined, Orig} end end; parse_auth(Orig = "Negotiate " ++ _Auth64) -> {undefined, undefined, Orig}; parse_auth(Orig) -> {undefined, undefined, Orig}. decode_base64([]) -> []; decode_base64(Auth64) -> decode_base64(Auth64, []). decode_base64([], Acc) -> lists:reverse(Acc); decode_base64([Sextet1,Sextet2,$=,$=|Rest], Acc) -> Bits2x6 = (d(Sextet1) bsl 18) bor (d(Sextet2) bsl 12), Octet1 = Bits2x6 bsr 16, decode_base64(Rest, [Octet1|Acc]); decode_base64([Sextet1,Sextet2,Sextet3,$=|Rest], Acc) -> Bits3x6 = (d(Sextet1) bsl 18) bor (d(Sextet2) bsl 12) bor (d(Sextet3) bsl 6), Octet1 = Bits3x6 bsr 16, Octet2 = (Bits3x6 bsr 8) band 16#ff, decode_base64(Rest, [Octet2,Octet1|Acc]); decode_base64([Sextet1,Sextet2,Sextet3,Sextet4|Rest], Acc) -> Bits4x6 = (d(Sextet1) bsl 18) bor (d(Sextet2) bsl 12) bor (d(Sextet3) bsl 6) bor d(Sextet4), Octet1 = Bits4x6 bsr 16, Octet2 = (Bits4x6 bsr 8) band 16#ff, Octet3 = Bits4x6 band 16#ff, decode_base64(Rest, [Octet3,Octet2,Octet1|Acc]); decode_base64(_CatchAll, _Acc) -> {error, bad_base64}. d(X) when X >= $A, X =<$Z -> X-65; d(X) when X >= $a, X =<$z -> X-71; d(X) when X >= $0, X =<$9 -> X+4; d($+) -> 62; d($/) -> 63; d(_) -> 63. flag(CurFlag, Bit, true) -> CurFlag bor Bit; flag(CurFlag, Bit, false) -> CurFlag band (bnot Bit). %% misc debug funcs .... use from cli only restart() -> stop(), load(), start(). modules() -> application:load(yaws), M = case application:get_all_key(yaws) of {ok, L} -> case lists:keysearch(modules, 1, L) of {value, {modules, Mods}} -> Mods; _ -> [] end; _ -> [] end, M. load() -> load(modules()). load(M) -> lists:foreach(fun(Mod) -> ?Debug("Load ~p~n", [Mod]), c:l(Mod) end, M). upto_char(Char, [Char|_]) -> []; upto_char(Char, [H|T]) when is_integer(H) -> [H|upto_char(Char, T)]; upto_char(_, []) -> []; %% deep lists upto_char(Char, [H|T]) when is_list(H) -> case lists:member(Char ,H) of true -> upto_char(Char, H); false -> [H, upto_char(Char, T)] end. %% map over deep list and maintain %% list structure as is deepmap(Fun, [H|T]) when is_list(H) -> [deepmap(Fun, H) | deepmap(Fun, T)]; deepmap(Fun, [H|T]) -> [Fun(H) | deepmap(Fun,T)]; deepmap(_Fun, []) -> []. sconf_to_srvstr(SC) -> redirect_scheme(SC) ++ redirect_host(SC,undefined). redirect_scheme(SC) -> case {SC#sconf.ssl,SC#sconf.rmethod} of {_, Method} when is_list(Method) -> Method++"://"; {undefined, _} -> "http://"; {_SSl, _} -> "https://" end. redirect_host(SC, HostHdr) -> case SC#sconf.rhost of undefined -> if HostHdr == undefined -> ServerName = SC#sconf.servername, SnameNoPort = case string:chr(ServerName, $:) of 0 -> ServerName; N -> lists:sublist(ServerName, N-1) end, SnameNoPort ++ redirect_port(SC); true -> HostHdr end; _ -> SC#sconf.rhost end. redirect_port(SC) -> case {SC#sconf.rmethod, SC#sconf.ssl, SC#sconf.port} of {"https", _, 443} -> ""; {"http", _, 80} -> ""; {_, undefined, 80} -> ""; {_, undefined, Port} -> [$:|erlang:integer_to_list(Port)]; {_, _SSL, 443} -> ""; {_, _SSL, Port} -> [$:|erlang:integer_to_list(Port)] end. redirect_scheme_port(SC) -> Scheme = redirect_scheme(SC), PortPart = redirect_port(SC), {Scheme, PortPart}. tmpdir() -> tmpdir(filename:join([home(), ".yaws"])). tmpdir(DefaultTmpDir) -> case os:type() of {win32,_} -> case os:getenv("TEMP") of false -> case os:getenv("TMP") of %% %% No temporary path set? %% Then try standard paths. %% false -> case file:read_file_info("C:/WINNT/Temp") of {error, _} -> "C:/WINDOWS/Temp"; {ok, _} -> "C:/WINNT/Temp" end; PathTMP -> PathTMP end; PathTEMP -> PathTEMP end; _ -> DefaultTmpDir end. %% mktemp function borrowed from Klacke's misc module %% Modified to use tmpdir/1 so it works on Windows too. %% Note that mktemp/2 could be exported too, but no Yaws %% code needs it, yet anyway. mktemp(Template) -> mktemp(Template, file). mktemp(Template, Ret) -> Tdir = tmpdir("/tmp"), Max = 1000, mktemp(Tdir, Template, Ret, 0, Max, ""). mktemp(Dir, Template, Ret, I, Max, Suffix) when I < Max -> {X,Y,Z} = unique_triple(), PostFix = erlang:integer_to_list(X) ++ "-" ++ erlang:integer_to_list(Y) ++ "-" ++ erlang:integer_to_list(Z), F = filename:join(Dir, Template ++ [$_ | PostFix] ++ Suffix), filelib:ensure_dir(F), case file:open(F, [read, raw]) of {error, enoent} when Ret == file -> {ok, F}; {error, enoent} when Ret == fd -> case file:open(F, [read, write, raw]) of {ok, Fd} -> file:delete(F), {ok, Fd}; Err -> Err end; {error, enoent} when Ret == binfd -> case file:open(F, [read, write, raw, binary]) of {ok, Fd} -> file:delete(F), {ok, Fd}; Err -> Err end; {ok, Fd} -> file:close(Fd), mktemp(Dir, Template, Ret, I+1, Max, Suffix); _Err -> mktemp(Dir, Template, Ret, I+1, Max, Suffix) end; mktemp(_Dir, _Template, _Ret, _I, _Max, _Suffix) -> {error, too_many}. %% This feature is usable together with %% privbind and authbind on linux home() -> case os:getenv("YAWSHOME") of false -> os:getenv("HOME"); DIR -> DIR end. id_dir(Id) -> filename:join([tmpdir(), "yaws", to_list(Id)]). ctl_file(Id) -> filename:join([id_dir(Id), "CTL"]). eat_crnl(Fd,SSL) -> setopts(Fd, [{packet, line}],SSL), case do_recv(Fd,0, SSL) of {ok, <<13,10>>} -> ok; {ok, [13,10]} -> ok; _ -> exit(normal) end. get_chunk_num(Fd, SSL) -> {N, _} = get_chunk_header(Fd, SSL), N. get_chunk_header(Fd, SSL) -> case do_recv(Fd, 0, SSL) of {ok, Data} -> Line = if is_binary(Data) -> binary_to_list(Data); true -> Data end, ?Debug("Get chunk num from line ~p~n",[Line]), {N, Exts} = split_at(Line, $;), {erlang:list_to_integer(strip_spaces(N),16), strip_spaces(Exts)}; {error, _Rsn} -> exit(normal) end. get_chunk(_Fd, N, N, _) -> []; get_chunk(Fd, N, Asz,SSL) -> case do_recv(Fd, N, SSL) of {ok, Bin} -> SZ = size(Bin), [Bin|get_chunk(Fd, N, SZ+Asz,SSL)]; _ -> exit(normal) end. get_chunk_trailer(Fd, SSL) -> Hdrs = #headers{}, case http_collect_headers(Fd, undefined, Hdrs, SSL, 0) of {error,_} -> exit(normal); Hdrs -> <<>>; NewHdrs -> {<<>>, NewHdrs} end. %% split inputstring at first occurrence of Char split_at(String, Char) -> split_at(String, Char, []). split_at([H|T], H, Ack) -> {lists:reverse(Ack), T}; split_at([H|T], Char, Ack) -> split_at(T, Char, [H|Ack]); split_at([], _Char, Ack) -> {lists:reverse(Ack), []}. %% insert an elemant at a given position into a list insert_at(Elm, 0, Ls) -> Ls ++ [Elm]; insert_at(Elm, Pos, Ls) -> insert_at(Elm, Pos, Ls, []). insert_at(Elm, _, [], Res) -> lists:reverse([Elm|Res]); insert_at(Elm, 1, Ls, Res) -> lists:reverse([Elm|Res]) ++ Ls; insert_at(Elm, Pos, [H|T], Res) -> insert_at(Elm, Pos-1, T, [H|Res]). %% Parse an Ip address or an Ip address range %% Return Ip || {IpMin, IpMax} where: %% Ip, IpMin, IpMax ::= ip_address() parse_ipmask(Str) when is_list(Str) -> case string:tokens(Str, [$/]) of [IpStr] -> case inet_parse:address(IpStr) of {ok, Ip} -> Ip; {error, Reason} -> throw({error, Reason}) end; [IpStr, NetMask] -> {Type, IpInt} = ip_to_integer(IpStr), MaskInt = netmask_to_integer(Type, NetMask), case netmask_to_wildcard(Type, MaskInt) of 0 -> integer_to_ip(Type, IpInt); Wildcard when Type =:= ipv4 -> NetAddr = (IpInt band MaskInt), Broadcast = NetAddr + Wildcard, IpMin = NetAddr + 1, IpMax = Broadcast - 1, {integer_to_ip(ipv4, IpMin), integer_to_ip(ipv4, IpMax)}; Wildcard when Type =:= ipv6 -> NetAddr = (IpInt band MaskInt), IpMin = NetAddr, IpMax = NetAddr + Wildcard, {integer_to_ip(ipv6, IpMin), integer_to_ip(ipv6, IpMax)} end; _ -> throw({error, einval}) end; parse_ipmask(_) -> throw({error, einval}). -define(MAXBITS_IPV4, 32). -define(MASK_IPV4, 16#FFFFFFFF). -define(MAXBITS_IPV6, 128). -define(MASK_IPV6, 16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF). ip_to_integer(Str) when is_list(Str) -> case inet_parse:address(Str) of {ok, Ip} -> ip_to_integer(Ip); {error, Reason} -> throw({error, Reason}) end; ip_to_integer({N1,N2,N3,N4}) -> <> = <>, if (Int bsr ?MAXBITS_IPV4) == 0 -> {ipv4, Int}; true -> throw({error, einval}) end; ip_to_integer({N1,N2,N3,N4,N5,N6,N7,N8}) -> <> = <>, if (Int bsr ?MAXBITS_IPV6) == 0 -> {ipv6, Int}; true -> throw({error, einval}) end; ip_to_integer(_) -> throw({error, einval}). integer_to_ip(ipv4, I) when is_integer(I), I =< ?MASK_IPV4 -> <> = <>, {N1, N2, N3, N4}; integer_to_ip(ipv6, I) when is_integer(I), I =< ?MASK_IPV6 -> <> = <>, {N1, N2, N3, N4, N5, N6, N7, N8}; integer_to_ip(_, _) -> throw({error, einval}). netmask_to_integer(Type, NetMask) -> case catch erlang:list_to_integer(NetMask) of I when is_integer(I) -> case Type of ipv4 -> (1 bsl ?MAXBITS_IPV4) - (1 bsl (?MAXBITS_IPV4 - I)); ipv6 -> (1 bsl ?MAXBITS_IPV6) - (1 bsl (?MAXBITS_IPV6 - I)) end; _ -> case ip_to_integer(NetMask) of {Type, MaskInt} -> MaskInt; _ -> throw({error, einval}) end end. netmask_to_wildcard(ipv4, Mask) -> ((1 bsl ?MAXBITS_IPV4) - 1) bxor Mask; netmask_to_wildcard(ipv6, Mask) -> ((1 bsl ?MAXBITS_IPV6) - 1) bxor Mask. %% Compare an ip to another ip or a range of ips match_ipmask(Ip, Ip) -> true; match_ipmask(Ip, {IpMin, IpMax}) -> case compare_ips(Ip, IpMin) of error -> false; less -> false; _ -> case compare_ips(Ip, IpMax) of error -> false; greater -> false; _ -> true end end; match_ipmask(_, _) -> false. compare_ips({A,B,C,D}, {A,B,C,D}) -> equal; compare_ips({A,B,C,D,E,F,G,H}, {A,B,C,D,E,F,G,H}) -> equal; compare_ips({A,B,C,D1}, {A,B,C,D2}) when D1 < D2 -> less; compare_ips({A,B,C,D1}, {A,B,C,D2}) when D1 > D2 -> greater; compare_ips({A,B,C1,_}, {A,B,C2,_}) when C1 < C2 -> less; compare_ips({A,B,C1,_}, {A,B,C2,_}) when C1 > C2 -> greater; compare_ips({A,B1,_,_}, {A,B2,_,_}) when B1 < B2 -> less; compare_ips({A,B1,_,_}, {A,B2,_,_}) when B1 > B2 -> greater; compare_ips({A1,_,_,_}, {A2,_,_,_}) when A1 < A2 -> less; compare_ips({A1,_,_,_}, {A2,_,_,_}) when A1 > A2 -> greater; compare_ips({A,B,C,D,E,F,G,H1}, {A,B,C,D,E,F,G,H2}) when H1 < H2 -> less; compare_ips({A,B,C,D,E,F,G,H1}, {A,B,C,D,E,F,G,H2}) when H1 > H2 -> greater; compare_ips({A,B,C,D,E,F,G1,_}, {A,B,C,D,E,F,G2,_}) when G1 < G2 -> less; compare_ips({A,B,C,D,E,F,G1,_}, {A,B,C,D,E,F,G2,_}) when G1 > G2 -> greater; compare_ips({A,B,C,D,E,F1,_,_}, {A,B,C,D,E,F2,_,_}) when F1 < F2 -> less; compare_ips({A,B,C,D,E,F1,_,_}, {A,B,C,D,E,F2,_,_}) when F1 > F2 -> greater; compare_ips({A,B,C,D,E1,_,_,_}, {A,B,C,D,E2,_,_,_}) when E1 < E2 -> less; compare_ips({A,B,C,D,E1,_,_,_}, {A,B,C,D,E2,_,_,_}) when E1 > E2 -> greater; compare_ips({A,B,C,D1,_,_,_,_}, {A,B,C,D2,_,_,_,_}) when D1 < D2 -> less; compare_ips({A,B,C,D1,_,_,_,_}, {A,B,C,D2,_,_,_,_}) when D1 > D2 -> greater; compare_ips({A,B,C1,_,_,_,_,_}, {A,B,C2,_,_,_,_,_}) when C1 < C2 -> less; compare_ips({A,B,C1,_,_,_,_,_}, {A,B,C2,_,_,_,_,_}) when C1 > C2 -> greater; compare_ips({A,B1,_,_,_,_,_,_}, {A,B2,_,_,_,_,_,_}) when B1 < B2 -> less; compare_ips({A,B1,_,_,_,_,_,_}, {A,B2,_,_,_,_,_,_}) when B1 > B2 -> greater; compare_ips({A1,_,_,_,_,_,_,_}, {A2,_,_,_,_,_,_,_}) when A1 < A2 -> less; compare_ips({A1,_,_,_,_,_,_,_}, {A2,_,_,_,_,_,_,_}) when A1 > A2 -> greater; compare_ips(_, _) -> error. %% ---- get_app_subdir(SubDir) when is_atom(SubDir) -> filename:join(get_app_dir(), atom_to_list(SubDir)). get_app_dir() -> case application:get_env(yaws, app_dir) of {ok, AppDir} -> AppDir; undefined -> AppDir = filename:absname( filename:dirname(filename:dirname(code:which(?MODULE))) ), application:set_env(yaws, app_dir, AppDir), AppDir end. get_ebin_dir() -> get_app_subdir(ebin). get_priv_dir() -> get_app_subdir(priv). get_inc_dir() -> get_app_subdir(include). yaws-2.0.2/src/yaws_sse.erl0000664000175000017500000000430412605311412012545 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_sse.erl %%% Author : Steve Vinoski %%% Purpose : Support for Server-Sent Events %%% Created : 31 May 2012 by Steve Vinoski %%%---------------------------------------------------------------------- -module(yaws_sse). -author('vinoski@ieee.org'). -export([headers/1, event/0, event/1, data/0, data/1, data/2, id/0, id/1, retry/0, retry/1, comment/1, send_events/2, send_events/3 ]). headers(StreamPid) -> [{status, 200}, {header, {"Cache-Control", "no-cache"}}, {header, {connection, "close"}}, {header, {transfer_encoding, erase}}, {streamcontent_from_pid, "text/event-stream", StreamPid}]. event() -> <<"event\n">>. event(EventName) -> [<<"event:">>, EventName, <<"\n">>]. data() -> <<"data\n">>. data(Data) -> [<<"data:">>, Data, <<"\n">>]. %% The version below trims out all embedded newlines. If you send data %% containing newlines using the version above, your events will be %% misinterpreted at the client. If the result of trimming includes %% any empty strings or binaries, they are dropped and not sent. data(Data0, [trim]) -> Bin = iolist_to_binary(Data0), Tokens = case catch binary:split(Bin, <<"\n">>, [global, trim]) of {'EXIT', {undef, [{binary,split,__}|_]}} -> %% handle older releases of Erlang Lst = binary_to_list(Bin), [Tok || Tok <- string:tokens(Lst, "\n")]; Bins -> [B || B <- Bins, B /= <<>>] end, [data(Data) || Data <- Tokens]. id() -> <<"id\n">>. id(Id) when is_integer(Id) -> [<<"id:">>, integer_to_list(Id), <<"\n">>]; id(Id) -> [<<"id:">>, Id, <<"\n">>]. retry() -> <<"retry\n">>. retry(ReconnectionTime) -> [<<"retry:">>, integer_to_list(ReconnectionTime), <<"\n">>]. comment(Comment) -> [<<":">>, Comment, <<"\n">>]. send_events(Socket, Events) -> send_events(Socket, Events, fun yaws_api:stream_process_deliver/2). send_events(Socket, Events, SendFun) -> SendFun(Socket, [Events, <<"\n">>]). yaws-2.0.2/src/json.erl0000664000175000017500000006747512605311412011703 00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED %%% WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED %%% %%% Use module json2.erl instead %%% %%% This module is deprecated. It uses list_to_atom and so could potentially %%% fill the atom table. It also fails to pass its own internal tests due to %%% changes made years ago outside the context of Yaws. %%% %%% Do not report problems with this module, as they will not be fixed. You %%% should instead convert your code to use the json2 module. %%% %%% WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED %%% WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED WARNING DEPRECATED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %(%% Copyright (c) 2005-2006, A2Z Development USA, Inc. All Rights Reserved. %%% %%% The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is A2Z Development USA, Inc. %%% All Rights Reserved. -module(json). -deprecated(module). -export([encode/1, decode_string/1, decode/2]). -export([is_obj/1, obj_new/0, obj_fetch/2, obj_find/2, obj_is_key/2]). -export([obj_store/3, obj_from_list/1, obj_fold/3]). -export([test/0]). -author("Jim Larson , Robert Wai-Chi Chu "). -author("Gaspar Chilingarov , Gurgen Tumanyan "). %%% JavaScript Object Notation ("JSON", http://www.json.org) is a simple %%% data syntax meant as a lightweight alternative to other representations, %%% such as XML. JSON is natively supported by JavaScript, but many %%% other languages have conversion libraries available. %%% %%% This module translates JSON types into the following Erlang types: %%% %%% JSON Erlang %%% ---- ------ %%% number number %%% string string %%% array {array, ElementList} %%% object tagged proplist with string (or atom) keys (i.e. {struct, PropList} ) %%% true, false, null atoms 'true', 'false', and 'null' %%% %%% Character Sets: the external representation, and the internal %%% representation of strings, are lists of UTF-16 code units. %%% The encoding of supplementary characters, as well as %%% transcoding to other schemes, such as UTF-8, can be provided %%% by other modules. (See discussion at %%% http://groups.yahoo.com/group/json/message/52) %%% %%%###################################################################### %%% UPD by Gaspar: for this moment utf-8 encoding inplemented by default %%% if incoming character list have symbols with codes %%% > 255 %%%###################################################################### %%% %%% Numbers: Thanks to Erlang's bignums, JSON-encoded integers of any %%% size can be parsed. Conversely, extremely large integers may %%% be JSON-encoded. This may cause problems for interoperability %%% with JSON parsers which can't handle arbitrary-sized integers. %%% Erlang's floats are of fixed precision and limited range, so %%% syntactically valid JSON floating-point numbers could silently %%% lose precision or noisily cause an overflow. However, most %%% other JSON libraries are likely to behave in the same way. %%% %%% Strings: If we represented JSON string data as Erlang binaries, %%% we would have to choose a particular unicode format. Instead, %%% we use lists of UTF-16 code units, which applications may then %%% change to binaries in their application-preferred manner. %%% %%% Arrays: Because of the string decision above, and Erlang's %%% lack of a distinguished string datatype, JSON arrays map %%% to Erlang tuples. Consider utilities like tuple_fold/3 %%% to deal with tuples in their native form. %%%###################################################################### %%% UPD by Gaspar: array changed to {array, ArrayElementList} %%% ArrayElementList -> list %%% to provide compatibility to xmlrpc module %%%###################################################################### %%% %%% Objects: Though not explicitly stated in the JSON "spec", %%% JSON's JavaScript heritage mandates that member names must %%% be unique within an object. The object/tuple ambiguity is %%% not a problem, since the atom 'struct' is not an %%% allowable value. Object keys may be atoms or strings on %%% encoding but are always decoded as strings. %%% %%%###################################################################### %%% UPD by Gaspar: struct changed to {array, PropList} %%% object keys always decoded to atoms to %%% provide full compatility with xmlrpc module %%%###################################################################### %%% %%% ENCODING %% Encode an erlang number, string, tuple, or object to JSON syntax, as a %% possibly deep list of UTF-16 code units, throwing a runtime error in the %% case of un-convertible input. %% Note: object keys may be either strings or atoms. encode(true) -> "true"; encode(false) -> "false"; encode(null) -> "null"; encode(undefined) -> "null"; encode(B) when is_binary(B) -> encode_string(B); encode(I) when is_integer(I) -> integer_to_list(I); encode(F) when is_float(F) -> float_to_list(F); encode(L) when is_list(L) -> case is_string(L) of yes -> encode_string(L); unicode -> encode_string(xmerl_ucs:to_utf8(L)); no -> encode({array, L}) end; encode({array, Props}) when is_list(Props) -> encode_array(Props); encode({struct, Props} = T) when is_list(Props) -> encode_object(T); encode(Bad) -> exit({json_encode, {bad_term, Bad}}). %% Encode an Erlang string to JSON. %% Accumulate strings in reverse. encode_string(B) when is_binary(B) -> encode_string(binary_to_list(B)); encode_string(S) -> encode_string(S, [$"]). encode_string([], Acc) -> lists:reverse([$" | Acc]); encode_string([C | Cs], Acc) -> case C of $" -> encode_string(Cs, [$", $\\ | Acc]); % (don't escape solidus on encode) $\\ -> encode_string(Cs, [$\\, $\\ | Acc]); $\b -> encode_string(Cs, [$b, $\\ | Acc]); % note missing \ $\f -> encode_string(Cs, [$f, $\\ | Acc]); $\n -> encode_string(Cs, [$n, $\\ | Acc]); $\r -> encode_string(Cs, [$r, $\\ | Acc]); $\t -> encode_string(Cs, [$t, $\\ | Acc]); C when C >= 0, C < $\s -> % Control characters must be unicode-encoded. Hex = lists:flatten(io_lib:format("~4.16.0b", [C])), encode_string(Cs, lists:reverse(Hex) ++ "u\\" ++ Acc); % " C when C =< 16#FFFF -> encode_string(Cs, [C | Acc]); _ -> exit({json_encode, {bad_char, C}}) end. %% Encode an Erlang object as a JSON object, allowing string or atom keys. %% Note that order is irrelevant in both internal and external object %% representations. Nevertheless, the output will respect the order %% of the input. encode_object({struct, _Props} = Obj) -> M = obj_fold(fun({Key, Value}, Acc) -> S = case Key of B when is_binary(B) -> encode_string(B); L when is_list(L) -> case is_string(L) of yes -> encode_string(L); unicode -> encode_string(xmerl_ucs:to_utf8(L)); no -> exit({json_encode, {bad_key, Key}}) end; A when is_atom(A) -> encode_string(atom_to_list(A)); _ -> exit({json_encode, {bad_key, Key}}) end, V = encode(Value), case Acc of [] -> [S, $:, V]; _ -> [Acc, $,, S, $:, V] end end, [], Obj), [${, M, $}]. %% Encode an Erlang tuple as a JSON array. %% Order *is* significant in a JSON array! encode_array(T) -> M = lists:foldl(fun(E, Acc) -> V = encode(E), case Acc of [] -> V; _ -> [Acc, $,, V] end end, [], T), [$[, M, $]]. %%% SCANNING %%% %%% Scanning funs return either: %%% {done, Result, LeftOverChars} %%% if a complete token is recognized, or %%% {more, Continuation} %%% if more input is needed. %%% Result is {ok, Term}, 'eof', or {error, Reason}. %%% Here, the Continuation is a simple Erlang string. %%% %%% Currently, error handling is rather crude - errors are recognized %%% by match failures. EOF is handled only by number scanning, where %%% it can delimit a number, and otherwise causes a match failure. %%% %%% Tokens are one of the following %%% JSON string -> erlang string %%% JSON number -> erlang number %%% true, false, null -> erlang atoms %%% { } [ ] : , -> lcbrace rcbrace lsbrace rsbrace colon comma token([]) -> {more, []}; token(eof) -> {done, eof, []}; token("true" ++ Rest) -> {done, {ok, true}, Rest}; token("tru") -> {more, "tru"}; token("tr") -> {more, "tr"}; token("t") -> {more, "t"}; token("false" ++ Rest) -> {done, {ok, false}, Rest}; token("fals") -> {more, "fals"}; token("fal") -> {more, "fal"}; token("fa") -> {more, "fa"}; token("f") -> {more, "f"}; token("null" ++ Rest) -> {done, {ok, null}, Rest}; token("nul") -> {more, "nul"}; token("nu") -> {more, "nu"}; token("n") -> {more, "n"}; token([C | Cs] = Input) -> case C of $\s -> token(Cs); % eat whitespace $\t -> token(Cs); % eat whitespace $\n -> token(Cs); % eat whitespace $\r -> token(Cs); % eat whitespace $" -> scan_string(Input); $- -> scan_number(Input); D when D >= $0, D =< $9-> scan_number(Input); ${ -> {done, {ok, lcbrace}, Cs}; $} -> {done, {ok, rcbrace}, Cs}; $[ -> {done, {ok, lsbrace}, Cs}; $] -> {done, {ok, rsbrace}, Cs}; $: -> {done, {ok, colon}, Cs}; $, -> {done, {ok, comma}, Cs}; $/ -> case scan_comment(Cs) of {more, X} -> {more, X}; {done, _, Chars} -> token(Chars) end; _ -> {done, {error, {bad_char, C}}, Cs} end. scan_string([$" | Cs] = Input) -> scan_string(Cs, [], Input). %% Accumulate in reverse order, save original start-of-string for continuation. scan_string([], _, X) -> {more, X}; scan_string(eof, _, X) -> {done, {error, missing_close_quote}, X}; scan_string([$" | Rest], A, _) -> {done, {ok, lists:reverse(A)}, Rest}; scan_string([$\\], _, X) -> {more, X}; scan_string([$\\, $u, U1, U2, U3, U4 | Rest], A, X) -> scan_string(Rest, [uni_char([U1, U2, U3, U4]) | A], X); scan_string([$\\, $u | _], _, X) -> {more, X}; scan_string([$\\, C | Rest], A, X) -> scan_string(Rest, [esc_to_char(C) | A], X); scan_string([C | Rest], A, X) -> scan_string(Rest, [C | A], X). %% Given a list of hex characters, convert to the corresponding integer. uni_char(HexList) -> erlang:list_to_integer(HexList, 16). esc_to_char($") -> $"; esc_to_char($/) -> $/; esc_to_char($\\) -> $\\; esc_to_char($b) -> $\b; esc_to_char($f) -> $\f; esc_to_char($n) -> $\n; esc_to_char($r) -> $\r; esc_to_char($t) -> $\t. scan_number([]) -> {more, []}; scan_number(eof) -> {done, {error, incomplete_number}, []}; scan_number([$-, $- | _Ds]) -> {done, {error, invalid_number}, []}; scan_number([$- | Ds] = Input) -> case scan_number(Ds) of {more, _Cont} -> {more, Input}; {done, {ok, N}, CharList} -> {done, {ok, -1 * N}, CharList}; {done, Other, Chars} -> {done, Other, Chars} end; scan_number([D | Ds] = Input) when D >= $0, D =< $9 -> scan_number(Ds, D - $0, Input). %% Numbers don't have a terminator, so stop at the first non-digit, %% and ask for more if we run out. scan_number([], _A, X) -> {more, X}; scan_number(eof, A, _X) -> {done, {ok, A}, eof}; scan_number([$.], _A, X) -> {more, X}; scan_number([$., D | Ds], A, X) when D >= $0, D =< $9 -> scan_fraction([D | Ds], A, X); scan_number([D | Ds], A, X) when A > 0, D >= $0, D =< $9 -> % Note that nonzero numbers can't start with "0". scan_number(Ds, 10 * A + (D - $0), X); scan_number([D | Ds], A, X) when D == $E; D == $e -> scan_exponent_begin(Ds, integer_to_list(A) ++ ".0", X); scan_number([D | _] = Ds, A, _X) when D < $0; D > $9 -> {done, {ok, A}, Ds}. scan_fraction(Ds, I, X) -> scan_fraction(Ds, [], I, X). scan_fraction([], _Fs, _I, X) -> {more, X}; scan_fraction(eof, Fs, I, _X) -> R = list_to_float(lists:append([integer_to_list(I), ".", lists:reverse(Fs)])), {done, {ok, R}, eof}; scan_fraction([D | Ds], Fs, I, X) when D >= $0, D =< $9 -> scan_fraction(Ds, [D | Fs], I, X); scan_fraction([D | Ds], Fs, I, X) when D == $E; D == $e -> R = lists:append([integer_to_list(I), ".", lists:reverse(Fs)]), scan_exponent_begin(Ds, R, X); scan_fraction(Rest, Fs, I, _X) -> R = list_to_float(lists:append([integer_to_list(I), ".", lists:reverse(Fs)])), {done, {ok, R}, Rest}. scan_exponent_begin(Ds, R, X) -> scan_exponent_begin(Ds, [], R, X). scan_exponent_begin([], _Es, _R, X) -> {more, X}; scan_exponent_begin(eof, _Es, _R, X) -> {done, {error, missing_exponent}, X}; scan_exponent_begin([D | Ds], Es, R, X) when D == $-; D == $+; D >= $0, D =< $9 -> scan_exponent(Ds, [D | Es], R, X). scan_exponent([], _Es, _R, X) -> {more, X}; scan_exponent(eof, Es, R, _X) -> X = list_to_float(lists:append([R, "e", lists:reverse(Es)])), {done, {ok, X}, eof}; scan_exponent([D | Ds], Es, R, X) when D >= $0, D =< $9 -> scan_exponent(Ds, [D | Es], R, X); scan_exponent(Rest, Es, R, _X) -> X = list_to_float(lists:append([R, "e", lists:reverse(Es)])), {done, {ok, X}, Rest}. scan_comment([]) -> {more, "/"}; scan_comment(eof) -> {done, eof, []}; scan_comment([$/ | Rest]) -> scan_cpp_comment(Rest); scan_comment([$* | Rest]) -> scan_c_comment(Rest). %% Ignore up to next CR or LF. If the line ends in CRLF, %% the LF will be treated as separate whitespace, which is %% okay since it will also be ignored. scan_cpp_comment([]) -> {more, "//"}; scan_cpp_comment(eof) -> {done, eof, []}; scan_cpp_comment([$\r | Rest]) -> {done, [], Rest}; scan_cpp_comment([$\n | Rest]) -> {done, [], Rest}; scan_cpp_comment([_ | Rest]) -> scan_cpp_comment(Rest). scan_c_comment([]) -> {more, "/*"}; scan_c_comment(eof) -> {done, eof, []}; scan_c_comment([$*]) -> {more, "/**"}; scan_c_comment([$*, $/ | Rest]) -> {done, [], Rest}; scan_c_comment([_ | Rest]) -> scan_c_comment(Rest). %%% PARSING %%% %%% The decode function takes a char list as input, but %%% interprets the end of the list as only an end to the available %%% input, and returns a "continuation" requesting more input. %%% When additional characters are available, they, and the %%% continuation, are fed into decode/2. You can use the atom 'eof' %%% as a character to signal a true end to the input stream, and %%% possibly flush out an unfinished number. The decode_string/1 %%% function appends 'eof' to its input and calls decode/1. %%% %%% Parsing and scanning errors are handled only by match failures. %%% The external caller must take care to wrap the call in a "catch" %%% or "try" if better error-handling is desired. Eventually parse %%% or scan errors will be returned explicitly with a description, %%% and someday with line numbers too. %%% %%% The parsing code uses a continuation-passing style to allow %%% for the parsing to suspend at any point and be resumed when %%% more input is available. %%% See http://en.wikipedia.org/wiki/Continuation_passing_style %% Return the first JSON value decoded from the input string. %% The string must contain at least one complete JSON value. decode_string(CharList) -> {done, V, _} = decode([], CharList ++ eof), V. %% Attempt to decode a JSON value from the input string %% and continuation, using empty list for the initial continuation. %% Return {done, Result, LeftoverChars} if a value is recognized, %% or {more, Continuation} if more input characters are needed. %% The Result can be {ok, Value}, eof, or {error, Reason}. %% The Continuation is then fed as an argument to decode/2 when %% more input is available. %% Use the atom 'eof' instead of a char list to signal %% a true end to the input, and may flush a final number. decode([], CharList) -> decode(first_continuation(), CharList); decode(Continuation, CharList) -> {OldChars, Kt} = Continuation, get_token(OldChars ++ CharList, Kt). first_continuation() -> {[], fun (eof, Cs) -> {done, eof, Cs}; (T, Cs) -> parse_value(T, Cs, fun(V, C2) -> {done, {ok, V}, C2} end) end}. %% Continuation Kt must accept (TokenOrEof, Chars) get_token(Chars, Kt) -> case token(Chars) of {done, {ok, T}, Rest} -> Kt(T, Rest); {done, eof, Rest} -> Kt(eof, Rest); {done, {error, Reason}, Rest} -> {done, {error, Reason}, Rest}; {more, X} -> {more, {X, Kt}} end. %% Continuation Kv must accept (Value, Chars) parse_value(eof, C, _Kv) -> {done, {error, premature_eof}, C}; parse_value(true, C, Kv) -> Kv(true, C); parse_value(false, C, Kv) -> Kv(false, C); parse_value(null, C, Kv) -> Kv(null, C); parse_value(S, C, Kv) when is_list(S) -> Kv(S, C); parse_value(N, C, Kv) when is_number(N) -> Kv(N, C); parse_value(lcbrace, C, Kv) -> parse_object(C, Kv); parse_value(lsbrace, C, Kv) -> parse_array(C, Kv); parse_value(_, C, _Kv) -> {done, {error, syntax_error}, C}. %% Continuation Kv must accept (Value, Chars) parse_object(Chars, Kv) -> get_token(Chars, fun(T, C2) -> Obj = obj_new(), case T of rcbrace -> Kv(Obj, C2); % empty object _ -> parse_object(Obj, T, C2, Kv) % token must be string end end). parse_object(_Obj, eof, C, _Kv) -> {done, {error, premature_eof}, C}; parse_object(Obj, S, C, Kv) when is_list(S) -> % S is member name get_token(C, fun (colon, C2) -> parse_object2(Obj, S, C2, Kv); (T, C2) -> {done, {error, {expecting_colon, T}}, C2} end); parse_object(_Obj, M, C, _Kv) -> {done, {error, {member_name_not_string, M}}, C}. parse_object2(Obj, S, C, Kv) -> get_token(C, fun (eof, C2) -> {done, {error, premature_eof}, C2}; (T, C2) -> parse_value(T, C2, fun(V, C3) -> % V is member value Obj2 = obj_store(S, V, Obj), get_token(C3, fun (rcbrace, C4) -> % "}" end of object {struct, PropList1} = Obj2, Kv({struct, lists:reverse(PropList1)}, C4); (comma, C4) -> % "," another member follows get_token(C4, fun(T3, C5) -> parse_object(Obj2, T3, C5, Kv) end); (eof, C4) -> {done, {error, premature_eof}, C4}; (T2, C4) -> {done, {error, {expecting_comma_or_curly, T2}}, C4} end) end) end). %% Continuation Kv must accept (Value, Chars) parse_array(C, Kv) -> get_token(C, fun (eof, C2) -> {done, {error, premature_eof}, C2}; (rsbrace, C2) -> Kv({array, []}, C2); % empty array (T, C2) -> parse_array([], T, C2, Kv) end). parse_array(E, T, C, Kv) -> parse_value(T, C, fun(V, C2) -> E2 = [V | E], get_token(C2, fun (rsbrace, C3) -> % "]" end of array Kv({array, lists:reverse(E2)}, C3); (comma, C3) -> % "," another value follows get_token(C3, fun(T3, C4) -> parse_array(E2, T3, C4, Kv) end); (eof, C3) -> {done, {error, premature_eof}, C3}; (T2, C3) -> {done, {error, {expecting_comma_or_close_array, T2}}, C3} end) end). %%% OBJECTS %%% %%% We'll use tagged property lists as the internal representation %%% of JSON objects. Unordered lists perform worse than trees for %%% lookup and modification of members, but we expect objects to be %%% have only a few members. Lists also print better. %% Is this a proper JSON object representation? is_obj({struct, Props}) when is_list(Props) -> lists:all(fun ({Member, _Value}) when is_atom(Member); is_list(Member) -> true; (_) -> false end, Props); is_obj(_) -> false. %% Create a new, empty object. obj_new() -> {struct, []}. %% Fetch an object member's value, expecting it to be in the object. %% Return value, runtime error if no member found with that name. obj_fetch(Key, {struct, Props}) when is_list(Props) -> case proplists:get_value(Key, Props) of undefined -> exit({struct_no_key, Key}); Value -> Value end. %% Fetch an object member's value, or indicate that there is no such member. %% Return {ok, Value} or 'error'. obj_find(Key, {struct, Props}) when is_list(Props) -> case proplists:get_value(Key, Props) of undefined -> error; Value -> {ok, Value} end. obj_is_key(Key, {struct, Props}) -> proplists:is_defined(Key, Props). %% Store a new member in an object. Returns a new object. obj_store(KeyList, Value, {struct, Props}) when is_list(Props) -> Key = try list_to_atom(KeyList) catch error:badarg -> KeyList end, {struct, [{Key, Value} | proplists:delete(Key, Props)]}. %% Create an object from a list of Key/Value pairs. obj_from_list(Props) -> Obj = {struct, Props}, case is_obj(Obj) of true -> Obj; false -> exit(json_bad_object) end. %% Fold Fun across object, with initial accumulator Acc. %% Fun should take (Value, Acc) as arguments and return Acc. obj_fold(Fun, Acc, {struct, Props}) -> lists:foldl(Fun, Acc, Props). is_string([]) -> yes; is_string(List) -> is_string(List, non_unicode). is_string([C|Rest], non_unicode) when is_integer(C), C >= 0, C =< 255 -> is_string(Rest, non_unicode); is_string([C|Rest], _) when is_integer(C), C>= 0, C =< 65000 -> is_string(Rest, unicode); is_string([], non_unicode) -> yes; is_string([], unicode) -> unicode; is_string(_, _) -> no. %%% TESTING %%% %%% We can't expect to round-trip from JSON -> Erlang -> JSON, %%% due to the degrees of freedom in the JSON syntax: whitespace, %%% and ordering of object members. We can, however, expect to %%% round-trip from Erlang -> JSON -> Erlang, so the JSON parsing %%% tests will in fact test the Erlang equivalence of the %%% JSON -> Erlang -> JSON -> Erlang coding chain. %% Test driver. Return 'ok' or {failed, Failures}. test() -> E2Js = e2j_test_vec(), Failures = lists:foldl(fun({E, J}, Fs) -> case (catch test_e2j(E, J)) of ok -> case (catch round_trip(E)) of ok -> case (catch round_trip_one_char(E)) of ok -> Fs; Reason -> [{round_trip_one_char, E, Reason} | Fs] end; Reason -> [{round_trip, E, Reason} | Fs] end; Reason -> [{erlang_to_json, E, J, Reason} | Fs] end; (end_of_tests, Fs) -> Fs end, [], E2Js), case Failures of [] -> ok; _ -> {failed, Failures} end. %% Test for conversion from Erlang to JSON. Note that unequal strings %% may represent equal JSON data, due to discretionary whitespace, %% object member order, trailing zeroes in floating point, etc. %% Legitimate changes to the encoding routines may require tweaks to %% the reference JSON strings in e2j_test_vec(). test_e2j(E, J) -> J2 = lists:flatten(encode(E)), J = J2, % raises error if unequal ok. %% Test that Erlang -> JSON -> Erlang round-trip yields equivalent term. round_trip(E) -> J2 = lists:flatten(encode(E)), {ok, E2} = decode_string(J2), true = equiv(E, E2), % raises error if false ok. %% Round-trip with one character at a time to test all continuations. round_trip_one_char(E) -> J = lists:flatten(encode(E)), {done, {ok, E2}, _} = lists:foldl(fun(C, Ret) -> case Ret of {done, _, _} -> Ret; {more, Cont} -> decode(Cont, [C]) end end, {more, first_continuation()}, J ++ [eof]), true = equiv(E, E2), % raises error if false ok. %% Test for equivalence of Erlang terms. %% Due to arbitrary order of construction, equivalent objects might %% compare unequal as erlang terms, so we need to carefully recurse %% through aggregates (tuples and objects). equiv({struct, Props1}, {struct, Props2}) -> equiv_object(Props1, Props2); equiv(T1, T2) when is_tuple(T1), is_tuple(T2) -> equiv_tuple(T1, T2); equiv(N1, N2) when is_number(N1), is_number(N2) -> N1 == N2; equiv(S1, S2) when is_list(S1), is_list(S2) -> S1 == S2; equiv(true, true) -> true; equiv(false, false) -> true; equiv(null, null) -> true. %% Object representation and traversal order is unknown. %% Use the sledgehammer and sort property lists. equiv_object(Props1, Props2) -> L1 = lists:keysort(1, Props1), L2 = lists:keysort(1, Props2), Pairs = lists:zip(L1, L2), true = lists:all(fun({{K1, V1}, {K2, V2}}) -> equiv(K1, K2) and equiv(V1, V2) end, Pairs). %% Recursively compare tuple elements for equivalence. equiv_tuple({}, {}) -> true; equiv_tuple(T1, T2) when size(T1) == size(T2) -> S = size(T1), lists:all(fun(I) -> equiv(element(I, T1), element(I, T2)) end, lists:seq(1, S)). e2j_test_vec() -> [ {1, "1"}, {3.1416, "3.14160"}, % text representation may truncate, trail zeroes {-1, "-1"}, {-3.1416, "-3.14160"}, {12.0e10, "1.20000e+11"}, {1.234E+10, "1.23400e+10"}, {-1.234E-10, "-1.23400e-10"}, {"foo", "\"foo\""}, {"foo" ++ [500] ++ "bar", [$", $f, $o, $o, 500, $b, $a, $r, $"]}, {"foo" ++ [5] ++ "bar", "\"foo\\u0005bar\""}, {"", "\"\""}, {[], "\"\""}, {"\n\n\n", "\"\\n\\n\\n\""}, {obj_new(), "{}"}, {obj_from_list([{"foo", "bar"}]), "{\"foo\":\"bar\"}"}, {obj_from_list([{"foo", "bar"}, {"baz", 123}]), "{\"foo\":\"bar\",\"baz\":123}"}, {{}, "[]"}, {{{}}, "[[]]"}, {{1, "foo"}, "[1,\"foo\"]"}, % json array in a json object {obj_from_list([{"foo", {123}}]), "{\"foo\":[123]}"}, % json object in a json object {obj_from_list([{"foo", obj_from_list([{"bar", true}])}]), "{\"foo\":{\"bar\":true}}"}, % fold evaluation order {obj_from_list([{"foo", {}}, {"bar", obj_from_list([{"baz", true}])}, {"alice", "bob"}]), "{\"foo\":[],\"bar\":{\"baz\":true},\"alice\":\"bob\"}"}, % json object in a json array {{-123, "foo", obj_from_list([{"bar", {}}]), null}, "[-123,\"foo\",{\"bar\":[]},null]"}, end_of_tests ]. %%% TODO: %%% %%% Measure the overhead of the CPS-based parser by writing a conventional %%% scanner-parser that expects all input to be available. %%% %%% JSON has dropped comments - disable their parsing. %%% %%% Allow a compile-time option to decode object member names as atoms, %%% to reduce the internal representation overheads when communicating %%% with trusted peers. yaws-2.0.2/src/yaws_log_file_h.erl0000664000175000017500000000510512605311412014042 00000000000000%%%------------------------------------------------------------------- %%% File : yaws_log_file_h.erl %%% Author : %%% Description : %%% %%% Created : 11 Mar 2004 by %%%------------------------------------------------------------------- %% Just extending the error_logger_file_h abit, %% If they change the internals of that module, this module %% breaks, but then again, the otp crew doesn't ever appear to %% change anything that might break anything ..... -module(yaws_log_file_h). -behaviour(gen_event). -include_lib("kernel/include/file.hrl"). -export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3]). %% This one is used when we are started directly. init(File) -> case error_logger_file_h:init(File) of {ok, {Fd, File, PrevHandler}} -> %% Pre 18.1 file:position(Fd, eof), {ok, {Fd, File, PrevHandler}}; {ok, {st, Fd, File, PrevHandler, Depth}} -> %% Post 18.1 file:position(Fd, eof), {ok, {st, Fd, File, PrevHandler, Depth}}; Error -> error_logger:error_msg( "Failed to set Yaws error report handler: ~p~n", [Error] ), Error end. %% Pre 18.1 handle_call(reopen, {Fd, File, Prev}) -> {ok, ok, {reopen(Fd,File), File, Prev}}; handle_call(wrap, {Fd, File, Prev}) -> {ok, ok, {wrap(Fd,File), File, Prev}}; handle_call(size, {Fd, File, Prev}) -> {ok, size(Fd,File), {Fd, File, Prev}}; %% Post 18.1 handle_call(reopen, {st, Fd, File, Prev, Depth}) -> {ok, ok, {st, reopen(Fd,File), File, Prev, Depth}}; handle_call(wrap, {st, Fd, File, Prev, Depth}) -> {ok, ok, {st, wrap(Fd,File), File, Prev, Depth}}; handle_call(size, {st, Fd, File, Prev, Depth}) -> {ok, size(Fd,File), {st, Fd, File, Prev, Depth}}; handle_call(X, S) -> error_logger_file_h:handle_call(X,S). handle_event(X, S) -> error_logger_file_h:handle_event(X, S). handle_info(X, S) -> error_logger_file_h:handle_info(X, S). terminate(Reason, State) -> error_logger_file_h:terminate(Reason, State). code_change(_OldVsn, State, _Extra) -> {ok, State}. reopen(Fd, File) -> file:close(Fd), {ok, Fd2} = file:open(File, [write,append]), Fd2. wrap(Fd, File) -> Old = File ++ ".old", file:delete(Old), file:close(Fd), file:rename(File, Old), {ok, Fd2} = file:open(File, [write,append]), Fd2. size(Fd, File) -> file:sync(Fd), case file:read_file_info(File) of {ok, FI} -> {ok, FI#file_info.size}; Error -> Error end. yaws-2.0.2/src/yaws_session_server.erl0000664000175000017500000003005212605311412015023 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_session_server.erl %%% Author : Claes Wikstrom %%% Purpose : maintain state for cookie sessions %%% Created : 17 Sep 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -module(yaws_session_server). -author('klacke@hyber.org'). -behaviour(gen_server). %% External exports -export([start_link/0, start/0, stop/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("../include/yaws_api.hrl"). -include("../include/yaws.hrl"). -export([new_session/1,new_session/2,new_session/3,new_session/4, cookieval_to_opaque/1, print_sessions/0, replace_session/2, replace_session/3, delete_session/1]). %% Default ETS backend callbacks -export ([init_backend/1, stop_backend/0, list/0, lookup/1, insert/1, delete/1, traverse/1, cleanup/0]). %% Utility functions for callbacks -export ([has_timedout/2, report_timedout_sess/1, cookie/1]). -define(TTL, (30 * 60)). % 30 minutes -record(ysession, {cookie, %% the cookie assigned to the session to, %% greg secs untill timeout death ttl, %% default time to live starttime, %% When calendar:local_time() did sess start cleanup, %% PID to notify of session end opaque %% any data the user supplies }). -record(state, {backend %% storage engine module }). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start_link() -> Backend = get_yaws_session_server_backend(), gen_server:start_link({local, yaws_session_server}, yaws_session_server, Backend, []). start() -> Backend = get_yaws_session_server_backend(), gen_server:start({local, yaws_session_server}, yaws_session_server, Backend, []). stop() -> gen_server:call(?MODULE, stop, infinity). %% We are bending over here in our pursuit of finding a %% proper ysession_server backend. get_yaws_session_server_backend() -> #gconf{ysession_mod = DefaultBackend} = #gconf{}, case yaws_server:getconf() of {ok, #gconf{ysession_mod = Backend}, _} -> Backend; _ -> case application:get_env(yaws, embedded) of {ok, true} -> case application:get_env(yaws, embedded_conf) of {ok, L} when is_list(L) -> case lists:keysearch(gc, 1, L) of {value, {_, #gconf{ysession_mod = Backend}}} -> Backend; _ -> DefaultBackend end; _ -> DefaultBackend end; _ -> DefaultBackend end end. %% will return a new cookie as a string new_session(Opaque) -> Call = {new_session, Opaque, ?TTL, undefined, undefined}, gen_server:call(?MODULE, Call, infinity). new_session(Opaque, TTL) -> Call = {new_session, Opaque, TTL, undefined, undefined}, gen_server:call(?MODULE, Call, infinity). new_session(Opaque, TTL, Cleanup) -> Call = {new_session, Opaque, TTL, Cleanup, undefined}, gen_server:call(?MODULE, Call, infinity). new_session(Opaque, TTL, Cleanup, Cookie) -> Call = {new_session, Opaque, TTL, Cleanup, Cookie}, gen_server:call(?MODULE, Call, infinity). cookieval_to_opaque(Cookie) -> gen_server:call(?MODULE, {cookieval_to_opaque, Cookie}, infinity). print_sessions() -> gen_server:cast(?MODULE, print_sessions). replace_session(Cookie, NewOpaque) -> gen_server:call(?MODULE, {replace_session, Cookie, NewOpaque, undefined}, infinity). replace_session(Cookie, NewOpaque, Cleanup) -> gen_server:call(?MODULE, {replace_session, Cookie, NewOpaque, Cleanup}, infinity). delete_session(CookieVal) -> gen_server:call(?MODULE, {delete_session, CookieVal}, infinity). %%%---------------------------------------------------------------------- %%% Callback functions from gen_server %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %%---------------------------------------------------------------------- init(Backend) -> Backend:init_backend(record_info(fields, ysession)), start_long_timer(), {ok, #state{backend = Backend}, to()}. %%---------------------------------------------------------------------- %% Func: handle_call/3 %% Returns: {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_call({new_session, Opaque, undefined, Cleanup, Cookie}, From, State) -> handle_call({new_session, Opaque, ?TTL, Cleanup, Cookie}, From, State); handle_call({new_session, Opaque, TTL, Cleanup, undefined}, From, State) -> N = bin2int(crypto:rand_bytes(16)), Cookie = atom_to_list(node()) ++ [$-|integer_to_list(N)], handle_call({new_session, Opaque, TTL, Cleanup, Cookie}, From, State); handle_call({new_session, Opaque, TTL, Cleanup, Cookie}, _From, State) -> Now = gnow(), TS = calendar:local_time(), NS = #ysession{cookie = Cookie, starttime = TS, opaque = Opaque, to = Now + TTL, ttl = TTL, cleanup = Cleanup}, Backend = State#state.backend, true = Backend:insert(NS), {reply, Cookie, State, to()}; handle_call({cookieval_to_opaque, Cookie}, _From, State) -> Backend = State#state.backend, Result = case Backend:lookup(Cookie) of [Y] -> Y2 = Y#ysession{to = gnow() + Y#ysession.ttl}, Backend:insert(Y2), {ok, Y#ysession.opaque}; [] -> {error, no_session} end, {reply, Result, State, to()}; handle_call({replace_session, Cookie, NewOpaque}, _From, State) -> handle_call({replace_session, Cookie, NewOpaque, undefined}, _From, State); handle_call({replace_session, Cookie, NewOpaque, Cleanup}, _From, State) -> Backend = State#state.backend, Result = case Backend:lookup(Cookie) of [Y] -> Y2 = Y#ysession{to = gnow() + Y#ysession.ttl, opaque = NewOpaque, cleanup = case Cleanup of undefined -> Y#ysession.cleanup; _ -> Cleanup end}, Backend:insert(Y2); [] -> error end, {reply, Result, State, to()}; handle_call({delete_session, CookieVal}, _From, State) -> Backend = State#state.backend, Result = case Backend:lookup(CookieVal) of [Y] -> Backend:delete(CookieVal), report_deleted_sess(Y); [] -> true end, {reply, Result, State, to()}; handle_call(stop, From, State) -> gen_server:reply(From, ok), {stop, normal, State}. %%---------------------------------------------------------------------- %% Func: handle_cast/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_cast(print_sessions, #state{backend = Backend} = State) -> Ss = Backend:list(), io:format("** ~p sessions active ~n~n", [length(Ss)]), N = gnow(), lists:foreach(fun(S) -> io:format("Cookie ~p ~n", [S#ysession.cookie]), io:format("Start ~p ~n", [S#ysession.starttime]), io:format("TTL ~p secs~n", [S#ysession.to - N]), io:format("Opaque ~p ~n~n~n", [S#ysession.opaque]), ok end, Ss), {noreply, State, to()}; handle_cast(_Msg, State) -> {noreply, State, to()}. %%---------------------------------------------------------------------- %% Func: handle_info/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_info(timeout, #state{backend = Backend} = State) -> Backend:traverse(gnow()), {noreply, State, to()}; handle_info(long_timeout, #state{backend = Backend} = State) -> Backend:traverse(gnow()), start_long_timer(), {noreply, State, to()}. %%---------------------------------------------------------------------- %% Func: terminate/2 %% Purpose: Shutdown the server %% Returns: any (ignored by gen_server) %%---------------------------------------------------------------------- terminate(_Reason, #state{backend = Backend}) -> Backend:stop_backend(), ok. %%---------------------------------------------------------------------- %% Func: code_change/3 %% Purpose: Handle upgrade %% Returns: new State data %%---------------------------------------------------------------------- code_change(_OldVsn, Data, _Extra) -> {ok, Data}. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- bin2int(Bin) -> lists:foldl(fun(N, Acc) -> Acc * 256 + N end, 0, binary_to_list(Bin)). %% timeout once every hour even if the server handles traffic all the time. start_long_timer() -> erlang:send_after(long_to(), self(), long_timeout). long_to() -> 60 * 60 * 1000. %% timeout if the server is idle for more than 2 minutes. to() -> 2 * 60 * 1000. gnow() -> calendar:datetime_to_gregorian_seconds( calendar:local_time()). send_cleanup_message(Sess,Msg) -> case Sess#ysession.cleanup of undefined -> nocleanup; Pid -> Pid ! Msg end. report_timedout_sess(S) -> send_cleanup_message(S,{yaws_session_end,timeout, S#ysession.cookie, S#ysession.opaque}). report_deleted_sess(S) -> send_cleanup_message(S,{yaws_session_end,normal, S#ysession.cookie, S#ysession.opaque}). has_timedout(Y, Time) -> Y#ysession.to =< Time. cookie(Y) -> Y#ysession.cookie. %% Backend callbacks (ETS as default) init_backend (_) -> ets:new(?MODULE, [set, named_table, public, {keypos, 2}]). stop_backend() -> ok. lookup(Key) -> ets:lookup(?MODULE, Key). insert(Session) -> ets:insert(?MODULE, Session). list() -> ets:tab2list(?MODULE). delete(Key) -> ets:delete(?MODULE, Key). cleanup() -> ets:delete_all_objects(?MODULE). traverse(N) -> traverse(N, ets:first(?MODULE)). traverse(_N, '$end_of_table') -> ok; traverse(N, Key) -> case lookup(Key) of [Y] -> case has_timedout(Y, N) of false -> traverse(N, ets:next(?MODULE, Key)); true -> report_timedout_sess(Y), Next = ets:next(?MODULE, Key), delete(Key), traverse(N, Next) end; [] -> traverse(N, ets:next(?MODULE, Key)) end. yaws-2.0.2/src/yaws.appup.src0000664000175000017500000000003512605311412013021 00000000000000{"%VSN%", [ ], [ ]}. yaws-2.0.2/src/yaws_vdir.erl0000664000175000017500000000350312605311412012717 00000000000000-module(yaws_vdir). -export([arg_rewrite/1]). -include("../include/yaws_api.hrl"). -export([join/2]). join(List, Sep) -> lists:foldl(fun(A, "") -> A; (A, Acc) -> Acc ++ Sep ++ A end, "", List). arg_rewrite(ARG) -> Req = ARG#arg.req, %%io:fwrite("----->rewrite_mod for request: ~p\n",[ARG#arg.req]), case Req#http_request.path of {abs_path, RawPath} -> case (catch yaws_api:url_decode_q_split(RawPath)) of {'EXIT', _} -> %%broken request - ignore let yaws_server handle it. ARG2 = ARG; {"", _QueryPart} -> ARG2 = ARG; {"/", _QueryPart} -> %%don't allow vdir to be specified for root - %% it doesn't make sense ARG2 = ARG; {DecPath, _QueryPart} -> SC = get(sc), %%vdirpath/3 will return the longest(ie most specific) %% 'virtual directory' match for our request %%It retrieves the vdir definitions from #arg.opaque case yaws_server:vdirpath(SC, ARG, DecPath) of {"",_MainDocRoot} -> %%no virtual dir corresponding to this %% http_request.path ARG2 = ARG; {Virt,DocRoot} -> %%the virtual-path of our request matches a %% vdir specification %% - rewrite ARG accordingly. ARG2 = ARG#arg{docroot = DocRoot, docroot_mount = Virt} end end; _Else -> ARG2 = ARG end, ARG2. yaws-2.0.2/src/yaws_sup_restarts.erl0000664000175000017500000000351212605311412014511 00000000000000%%% File : yaws_sup_restarts.erl %%% Author : Claes Wikstrom %%% Description : Procs that can be restarted %%% Created : 13 Jan 2009 by Claes Wikstrom -module(yaws_sup_restarts). -behaviour(supervisor). %% External exports -export([start_link/0]). %% supervisor callbacks -export([init/1]). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). %%%---------------------------------------------------------------------- %%% Callback functions from supervisor %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- init([]) -> Sess = {yaws_session_server, {yaws_session_server, start_link, []}, permanent, 5000, worker, [yaws_session_server]}, YawsRSS = {yaws_rss, {yaws_rss, start_link, []}, permanent, 5000, worker, [yaws_rss]}, YawsEventManager = {yaws_event_manager, {gen_event, start_link,[{local,yaws_event_manager}]}, permanent, 5000, worker, [gen_event]}, %% below, ignore dialyzer warning: %% "The pattern 'false' can never match the type 'true'" SendFile = case yaws_sendfile:have_sendfile() of true -> [{yaws_sendfile, {yaws_sendfile, start_link, []}, permanent, 5000, worker, [yaws_sendfile]}]; false -> [] end, {ok,{{one_for_one, 1, 60}, [Sess, YawsRSS, YawsEventManager] ++ SendFile}}. yaws-2.0.2/src/yaws_debug.hrl0000664000175000017500000000421312605311412013043 00000000000000%%%---------------------------------------------------------------------- %%% File : yaws_debug.hrl %%% Author : Claes Wikstrom %%% Purpose : %%% Created : 7 Feb 2002 by Claes Wikstrom %%%---------------------------------------------------------------------- -author('klacke@hyber.org'). -define(F(Format,Args), lists:flatten(io_lib:format(Format,Args))). -define(f(L), lists:flatten(L)). -define(W(A), ?F("~w", [A])). -define(format_record(Rec, Name), yaws_debug:format_record(Rec, Name, record_info(fields, Name))). -define(Trace(What, Fmt, Args), if Trace == false -> ok; _ -> yaws_debug:dtrace(What,Fmt,Args) end). -ifdef(debug). %% Possible Ops are, equal | neq | integer | list | {list, length, equal} %% | greater | min | max | interval | {in, X , List} -define(Dassert(X,Op,Y,Msg), yaws_debug:assert(Op,X,Y,{assert,?FILE,?LINE,Msg})). -define(Dalert(X,Op,Y,Msg), yaws_debug:assert(Op,X,Y,{alert,?FILE,?LINE,Msg})). -define(Deval(Expr),Expr). -define(Debug(F, A), yaws_debug:assert([],0,0,{{debug,"DEBUG"}, ?FILE,?LINE,F, A})). %% ease of use, just do ?Dvar(Variable) -define(Dvar(Var), ?Debug("Var = ~p~n", [Var])). -define(TC(L), yaws_debug:typecheck(L, ?FILE, ?LINE)). -define(Derror(Fmt,Args), yaws_debug:assert([],0,0,{{debug,"ERROR"}, ?FILE,?LINE,Fmt,Args})). -define(Dformat(Fmt,Args), yaws_debug:assert([],0,0,{format, ?FILE,?LINE,Fmt,Args})). -define(Dfunassert(Fun, Msg), yaws_debug:assert('fun', Fun, 0, {assert,?FILE,?LINE,Msg})). -else. %% not debug_mode -define(DLOG(F, A), ?LOG(F, A)). -define(Dassert(X,Op,Y,Msg),debug_disabled). -define(Dalert(X,Op,Y,Msg),debug_disabled). -define(Deval(Expr),debug_disabled). -define(Debug(F, A),debug_disabled). -define(Dvar(Var), debug_disabled). -define(Dformat(Fmt,Args),debug_disabled). -define(Dfunassert(Fun, Msg), debug_disabled). -define(Derror(Fmt,Args),debug_disabled). -define(TC(L), debug_disabled). -endif. %% debug defined yaws-2.0.2/src/yaws_appmod_cgi.erl0000664000175000017500000000050512605311412014054 00000000000000%%% File : yaws_appmod_cgi.erl %%% Author : Claes Wikstrom %%% Description : %%% Created : 10 Mar 2008 by Claes Wikstrom -module(yaws_appmod_cgi). -export([out/1]). -include("../include/yaws_api.hrl"). out(Arg) -> yaws_cgi:call_cgi(Arg, lists:flatten(Arg#arg.fullpath)). yaws-2.0.2/src/yaws_dime.erl0000664000175000017500000002271112605311412012673 00000000000000%%%------------------------------------------------------------------- %%% File : dime.erl %%% @author Anders Nygren %%% @doc Encoding and decoding of DIME messages. %%% The Direct Internet Message Encapsulation (DIME) specification %%% defines a mechanism for packaging binary data with SOAP messages. %%% http://bgp.potaroo.net/ietf/all-ids/draft-nielsen-dime-02.txt %%% Layout of a DIME encoded message is like this %%%
%%%  0                   1                   2                   3
%%%  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
%%% |         |M|M|C|       |       |                               |
%%% | VERSION |B|E|F| TYPE_T| RESRVD|         OPTIONS_LENGTH        |
%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
%%% |            ID_LENGTH          |           TYPE_LENGTH         |
%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
%%% |                          DATA_LENGTH                          |
%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
%%% |                                                               /
%%% /                     OPTIONS + PADDING                         /
%%% /                                                               |
%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
%%% |                                                               /
%%% /                          ID + PADDING                         /
%%% /                                                               |
%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
%%% |                                                               /
%%% /                        TYPE + PADDING                         /
%%% /                                                               |
%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
%%% |                                                               /
%%% /                        DATA + PADDING                         /
%%% /                                                               |
%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
%%%
%%% @end
%%%
%%% Created :  7 Apr 2008 by Anders Nygren <>
%%%-------------------------------------------------------------------
-module(yaws_dime).

%% API
-export([encode/2,
         decode/1,
         pad_len/1]).


-include_lib("kernel/include/file.hrl").

-define(VERSION1, 1).
-define(T_UNCHANGED, 0).
-define(T_MEDIA_TYPE, 1).
-define(T_ABS_URI, 2).
-define(T_UNKNOWN, 3).
-define(T_NONE, 4).
-define(SOAP_URI, "http://schemas.xmlsoap.org/soap/envelope").
%%====================================================================
%% API
%%====================================================================
%%--------------------------------------------------------------------
%% @spec (Req, Attachments) ->binary()
%% Description:
%%--------------------------------------------------------------------
encode(Req, []) ->
    encode_part(1, 1, 0, ?T_ABS_URI, <<"">>, <<"">>, <>, Req);
encode(Req, As) ->
        list_to_binary([encode_part(1, 0, 0, ?T_ABS_URI,
                                    <<"">>, <<"">>, <>, Req)|
        encode_attachments(As)]).

encode_attachments([{attachment, Id, Type, File}]) ->
    [encode_part(0, 1, 0, ?T_ABS_URI, <<"">>, list_to_binary(Id),
                 list_to_binary(Type), File)];
encode_attachments([{attachment, Id, Type, File} | As]) ->
    [encode_part(0, 0, 0, ?T_ABS_URI, <<"">>, list_to_binary(Id),
                 list_to_binary(Type), File)|
     encode_attachments(As)].

encode_part(MB, ME, CF, TypeT, Opts, ID, Type, Data) ->
    Opts_len = size_of(Opts),
    Opts_pad = pad_len(Opts_len),
    Id_len = size_of(ID),
    Id_pad = pad_len(Id_len),
    Type_len = size_of(Type),
    Type_pad = pad_len(Type_len),
    Data_len = size_of(Data),
    Data_pad = pad_len(Data_len),
    Data1 = get_data(Data),
    <>.

pad_len(Len) ->
    case Len rem 4 of
        0 ->
            0;
        N ->
            4-N
    end.

size_of(X) when is_list(X) ->
    length(X);
size_of(X) when is_binary(X)->
    size(X);
size_of({file, File}) ->
    {ok,R} = file:read_file_info(File),
    R#file_info.size.

get_data({file, File}) ->
    {ok, Data} = file:read_file(File),
    Data;
get_data(Data) when is_list(Data) ->
    list_to_binary(Data);

get_data(Data) ->
    Data.
%%--------------------------------------------------------------------
%% @spec (Msg::binary()) ->
%% @doc Decode a DIME encoded message.
%%--------------------------------------------------------------------
decode(Msg) ->
    decode_recs(Msg, [], []).

decode_recs(<<>>, Acc, _Chunks) ->
    Acc;
decode_recs(Msg, Acc, Chunks) ->
    case {decode_rec(Msg), Chunks} of
        %% A normal record
        {{_ME=0, _CF=0, Opts, ID, Type, Chunk, More}, []} ->
            decode_recs(More, [{Opts, ID, Type, Chunk}|Acc], []);

        %% The last chunk of a block, but not the last record
        {{_ME=0, _CF=0, Opts, ID, Type, Chunk, More}, Chunks} ->
            Cs = lists:reverse([{Opts, ID, Type, Chunk}|Chunks]),
            %% Only the first chunk has values for Opts, Id and Type
            {ROpts, RID, RType, _Chunk} = hd(Cs),
            Block = list_to_binary([Ch || {_Opts, _ID, _Type, Ch} <- Cs]),
            error_logger:info_report([?MODULE, decode_rec, merging,
                                      {id, ID},{type, Type},
                                      {chunks, length(Cs)}]),
            decode_recs(More, [{ROpts, RID, RType, Block}|Acc], []);

        %% Last record, but not chunked
        {{_ME=1, _CF=0, Opts, ID, Type, Data, _More}, []} ->
            lists:reverse([{Opts, ID, Type, Data}|Acc]);

        %% Last record, and last chunk of block
        {{_ME=1, _CF=0, Opts, ID, Type, Chunk, _More}, Chunks} ->
            Cs = lists:reverse([{Opts, ID, Type, Chunk}|Chunks]),
            {ROpts, RID, RType, _Chunk} = hd(Cs),
            Block = list_to_binary([Ch || {_Opts, _ID, _Type, Ch} <- Cs]),
            error_logger:info_report([?MODULE, decode_rec, merging,
                                      {id, ID},{type, Type},
                                      {chunks, length(Cs)}]),
            lists:reverse([{ROpts, RID, RType, Block}|Acc]);

        %% First or intermediate chunk, but not the last
        {{_ME=0, _CF=1, Opts, ID, Type, Data, More}, Chunks} ->
            decode_recs(More, Acc, [{Opts, ID, Type, Data}|Chunks]);

        %% Something wrong, ME=1 and CF=1
        ErrorResult ->
                error_logger:error_report([?MODULE, decode_recs,
                                           {result, ErrorResult}])
    end.

decode_rec(<>=Block) ->
    error_logger:info_report([?MODULE, decode_rec,
                              {version,1},
                              {mb,_MB},{me,ME},{cf,CF},{type_t,_Type_T},
                              {res,_Res},{opt_len,Opt_Len},{id_len,ID_Len},
                              {type_len,Type_Len},{date_len,Data_Len},
                              {total_rec_size,byte_size(Block)}]),
    Opt_pad = pad_len(Opt_Len),
    Id_pad = pad_len(ID_Len),
    Type_pad = pad_len(Type_Len),
    Data_pad = pad_len(Data_Len),
    Header = Opt_Len+Opt_pad+ID_Len+Id_pad+Type_Len+Type_pad,
    DataTot = Data_Len+Data_pad,
    case byte_size(Rest) of
        N when N >= Header+DataTot ->
            <> = Rest,
            {ME, CF, Opts, ID, Type, Data, More};
        N when N > Header->
            <> = Rest,
            error_logger:error_report([?MODULE, decode_rec, short_record,
                                       {need, Header+DataTot},
                                       {has, N}]),
            {ME, CF, Opts, ID, Type, Data, <<>>};
        N ->
            error_logger:error_report([?MODULE, decode_rec, short_record,
                                       {need, Header+DataTot},
                                       {has, N}]),
            {error, not_enough_data}
    end;

decode_rec(Bin) ->
    error_logger:error_report([?MODULE, decode_rec, short_record,
                               no_header,
                               {has, byte_size(Bin)}]),
    {error, no_header}.


%%====================================================================
%% Internal functions
%%====================================================================
yaws-2.0.2/src/yaws_cgi.erl0000664000175000017500000014375112605311412012527 00000000000000-module(yaws_cgi).
-author('carsten@codimi.de').
-author('brunorijsman@hotmail.com').         %% Added support for FastCGI

-include("../include/yaws_api.hrl").
-include("yaws_debug.hrl").
-include("../include/yaws.hrl").

%%% Returns Out (i.e. same return values as out/1).
%%%
-export([call_cgi/5, call_cgi/4, call_cgi/3, call_cgi/2]).
-export([call_fcgi_responder/2, call_fcgi_responder/1]).

%%% Returns {allowed, Out} or {denied, Out}.
%%%
-export([call_fcgi_authorizer/2, call_fcgi_authorizer/1]).

%%% Returns [{VariableName, VariableValue}].
%%%
-export([fcgi_extract_variables/1]).

%%% TODO: Implement FastCGI filter role.

-export([cgi_worker/7, fcgi_worker/6]).

%%%=====================================================================
%%% Code shared between CGI and FastCGI
%%%=====================================================================

-define(ASCII_NEW_LINE, 10).
-define(ASCII_CARRIAGE_RETURN, 13).


handle_clidata(Arg, WorkerPid) ->
    case Arg#arg.clidata of
        undefined ->
            end_of_clidata(Arg, WorkerPid);
        {partial, Data} ->
            send_clidata(WorkerPid, Data),
            {get_more, cgicont, {cgistate, WorkerPid}};
        Data when is_binary(Data) ->
            send_clidata(WorkerPid, Data),
            end_of_clidata(Arg, WorkerPid)
    end.


end_of_clidata(Arg, WorkerPid) ->
    WorkerPid ! {self(), end_of_clidata},
    get_from_worker(Arg, WorkerPid).


send_clidata(WorkerPid, Data) ->
    WorkerPid ! {self(), clidata, Data},
    receive
        {WorkerPid, clidata_receipt} -> ok
    end.


get_from_worker(Arg, WorkerPid) ->
    case get_resp(WorkerPid) of
        {failure, Reason} ->
            [{status, 500}, {html, io_lib:format("CGI failure: ~p", [Reason])}];
        {Headers, Data} ->
            AllResps = lists:map(fun(X)-> do_header(Arg, X, Data) end, Headers),
            %%
            %% The CGI 1.1 spec (RFC 3875) requires a worker response
            %% consisting of only a location header and optional extension
            %% headers to be augmented with a 302 status code. Any other
            %% worker response with a location header is handled normally.
            %% Technically a response of the latter type MUST have a status
            %% code in it, but we don't enforce that.
            %%
            {LocHdr, _ExtHdrs, TheRest} =
                lists:foldl(
                  fun({header, Line}=Hdr, {Loc, Ext, Rest}) ->
                          {HdrLower, _HdrVal} = do_lower_header(Line),
                          case HdrLower of
                              "location" ->
                                  {[Hdr], Ext, Rest};
                              "x-cgi-"++_ ->
                                  {Loc, [Hdr|Ext], Rest};
                              _ ->
                                  {Loc, Ext, [Hdr|Rest]}
                          end;
                     (Hdr, {Loc, Ext, Rest}) ->
                          {Loc, Ext, [Hdr|Rest]}
                  end, {[], [], []}, AllResps),
            Next = case LocHdr of
                       [] ->
                           normal;
                       [{header, _Location}] ->
                           case TheRest of
                               [] ->
                                   location_add_302;
                               _ ->
                                   normal
                           end
                   end,
            case Next of
                normal ->
                    {ContentResps, NotCtnt} =
                        filter2(fun iscontent/1, AllResps),
                    {RedirResps, Others} = filter2(fun isredirect/1, NotCtnt),
                    case RedirResps of
                        [R|_] ->
                            WorkerPid ! {self(), no_data},
                            Others ++ [R];
                        [] ->
                            case ContentResps of
                                [C={streamcontent, _, _}|_] ->
                                    WorkerPid ! {self(), stream_data},
                                    Others++[C];
                                [C={content, _, _}|_] ->
                                    WorkerPid ! {self(), no_data},
                                    Others++[C];
                                [] ->
                                    WorkerPid ! {self(), no_data},
                                    Others
                            end
                    end;
                location_add_302 ->
                    WorkerPid ! {self(), no_data},
                    AllResps++[{status, 302}]
            end
    end.


filter2(Pred, Xs) ->
    filter2(Pred, Xs, [], []).

filter2(_Pred, [], Ts, Fs) ->
    {lists:reverse(Ts), lists:reverse(Fs)};
filter2(Pred, [X|Xs], Ts, Fs) ->
    case Pred(X) of
        true ->
            filter2(Pred, Xs, [X|Ts], Fs);
        false ->
            filter2(Pred, Xs, Ts, [X|Fs])
    end.


iscontent({content, _, _}) ->
    true;
iscontent({streamcontent, _, _}) ->
    true;
iscontent(_) ->
    false.

isredirect({status, I}) when is_integer(I) , I > 301, I < 304; I =:= 307 ->
    true;
isredirect(_) ->
    false.

checkdef(undefined) ->
    "";
checkdef(L) ->
    L.


deep_drop_prefix([], L) ->
    L;
deep_drop_prefix([X|Xs], [X|Ys]) when is_integer(X) ->
    deep_drop_prefix(Xs, Ys);
deep_drop_prefix([X|Xs], Ys) when is_list(X) ->
    deep_drop_prefix(X++Xs, Ys);
deep_drop_prefix(Xs, [Y|Ys]) when is_list(Y) ->
    deep_drop_prefix(Xs, Y++Ys);
deep_drop_prefix(_, _) ->
    false.


get_socket_peername({ssl, SslSocket}) ->
    {ok, {IP, _Port}}=ssl:peername(SslSocket),
    inet_parse:ntoa(IP);
get_socket_peername(Socket) ->
    {ok, {IP, _Port}}=inet:peername(Socket),
    inet_parse:ntoa(IP).


get_socket_sockname({ssl, SslSocket}) ->
    {ok, {IP, _Port}}=ssl:sockname(SslSocket),
    inet_parse:ntoa(IP);
get_socket_sockname(Socket) ->
    {ok, {IP, _Port}}=inet:sockname(Socket),
    inet_parse:ntoa(IP).


build_env(Arg, Scriptfilename, Pathinfo, ExtraEnv, SC) ->
    H       = Arg#arg.headers,
    Req     = Arg#arg.req,
    OrigReq = Arg#arg.orig_req,

    %% Use the original request to set REQUEST_URI
    case OrigReq#http_request.path of
        {abs_path, RequestURI} -> ok;
        _ -> RequestURI = undefined
    end,
    {Maj,Min} = Req#http_request.version,
    {Hostname, Hosttail}=lists:splitwith(fun(X)->X /= $: end,
                                         checkdef(H#headers.host)),
    Hostport = case Hosttail of
                   [$: | P] -> P;
                   [] -> integer_to_list(SC#sconf.port)
               end,
    PeerAddr = get_socket_peername(Arg#arg.clisock),
    LocalAddr = get_socket_sockname(Arg#arg.clisock),

    Scheme = (catch yaws:redirect_scheme(SC)),
    %% Needed by trac, for redirs after POST
    HttpsEnv  = case Scheme of
                    "https://" -> [{"HTTPS", "1"}];
                    _ ->[]
                end,


    %%Scriptname = deep_drop_prefix(Arg#arg.docroot, Arg#arg.fullpath),
    %%SCRIPT_NAME is the path of the script relative to the root of the website.
    %%just dropping docroot from the fullpath does not give the full SCRIPT_NAME
    %% path if a 'vdir' is involved.
    UriTail = deep_drop_prefix(Arg#arg.docroot, Arg#arg.fullpath),
    case Arg#arg.docroot_mount of
        "/" ->
            %%no arg.docroot_mount means that arg.docroot
            %% corresponds to the URI-root of the request "/"
            Scriptname = UriTail;
        Vdir ->
            Scriptname = Vdir ++ string:strip(UriTail,left,$/)
    end,

    Pathinfo2 = checkdef(Pathinfo),
    case Pathinfo2 of
        "" ->
            PathTranslated = "";
        _ ->
            %%determine what physical path the server would map Pathinfo2
            %%to if it had received just Pathinfo2 in the request.
            PathTranslated = yaws_server:mappath(SC,Arg,Pathinfo2)
    end,


    %%Pass auth info in environment - yes - including password in plain text.
    %%REMOTE_USER always = AUTH_USER
    %%!todo - LOGON_USER - same as AUTH_USER unless some auth filter has mapped
    %%the user to another username under which to run the request.
    case H#headers.authorization of
        undefined ->
            AuthEnv = [];
        {undefined, _, _} ->
            AuthEnv = [];
        {User, Password, "Basic " ++ Auth64} ->
            AuthEnv = [
                       {"HTTP_AUTHORIZATION", "Basic " ++ Auth64},
                       {"AUTH_TYPE", "Basic"},
                       {"AUTH_USER", User},
                       {"REMOTE_USER", User},
                       {"LOGON_USER", User},
                       {"AUTH_PASSWORD", Password}
                      ];
        {_User, _Password, _OrigString} ->
            %%not attempting to pass through any auth info for
            %% auth schemes that we don't yet handle
            AuthEnv = []
    end,

    Extra_CGI_Vars = lists:flatmap(fun({Dir, Vars}) ->
                                           case lists:prefix(Dir, Scriptname) of
                                               true -> Vars;
                                               false -> []
                                           end
                                   end,
                                   SC#sconf.extra_cgi_vars),

    %% Some versions of erlang:open_port can't handle query strings that
    %% end with an equal sign. This is because the broken versions treat
    %% environment variable strings ending with '=' as environment variable
    %% names intended to be deleted from the environment, i.e. as if they
    %% have no value. The result is that no QUERY_STRING environment
    %% variable gets set for these cases. We work around this by appending
    %% a & character to any query string that ends in =.
    QueryString = case checkdef(Arg#arg.querydata) of
                      "" ->
                          "";
                      QS ->
                          case lists:reverse(QS) of
                              [$= | _] ->
                                  QS ++ "&";
                              _ ->
                                  QS
                          end
                  end,

    %%todo - review. should AuthEnv entries be overridable by ExtraEnv or not?
    %% we should define policy here rather than let through dupes.

    ExtraEnv ++
        HttpsEnv ++
        AuthEnv ++
        lists:filter(
          fun({K, L}) when is_list(L) ->
                  case lists:keysearch(K, 1, ExtraEnv) of
                      false ->
                          true;
                      _ ->
                          %% we have override in extraenv
                          false
                  end;
             (_) ->
                  false
          end,
          ([
            {"SERVER_SOFTWARE", "Yaws/"++yaws_generated:version()},
            {"SERVER_NAME", Hostname},
            {"HTTP_HOST", checkdef(H#headers.host)},
            {"GATEWAY_INTERFACE", "CGI/1.1"},
            {"SERVER_PROTOCOL", "HTTP/" ++ integer_to_list(Maj) ++
             "." ++ integer_to_list(Min)},
            {"SERVER_PORT", Hostport},
            {"REQUEST_METHOD", yaws:to_list(Req#http_request.method)},
            {"REQUEST_URI", RequestURI},
            {"DOCUMENT_ROOT",         Arg#arg.docroot},
            {"DOCUMENT_ROOT_MOUNT", Arg#arg.docroot_mount},
            %% SCRIPT_FILENAME is for PHP 4.3.2 and higher
            %% see http://bugs.php.net/bug.php?id=28227
            %% (Sergei Golovan).
            {"SCRIPT_FILENAME", Scriptfilename},
            %% {"SCRIPT_TRANSLATED", Scriptfilename},   %IIS6+
            {"PATH_INFO",                Pathinfo2},
            {"PATH_TRANSLATED",        PathTranslated},
            %% 
            %%  CGI/1.1 spec says PATH_TRANSLATED should be NULL or unset
            %% if PATH_INFO is NULL
            %%  This is in contrast to IIS behaviour - and may break some apps.
            %%  broken apps that expect it to always correspond to path of
            %% script
            %%  should be modified to use SCRIPT_FILENAME instead - or wrapped.
            %% 
            %% --------------------
            %%  
            %%  This seems not to
            %%  correspond to the
            %%  documentation I have
            %%  read, but it works
            %%  with PHP.
            %%
            %%  (Not with PHP 4.3.10-16) from
            %%  Debian sarge (Sergei Golovan).
            %%  
            %% ---------------------
            {"SCRIPT_NAME", Scriptname},
            {"REMOTE_ADDR", PeerAddr},
            {"REMOTE_HOST", PeerAddr},  %%  We SHOULD send this
            %%  Resolving DNS not practical for performance reasons
            %%  - at least on 1st contact from a particular host.
            %%  we could do background lookup so that it's available
            %% for subsequent invocations,
            %%  but it hardly seems worthwhile. We are permitted by the
            %% CGI/1.1 spec to substitute REMOTE_ADDR
            {"SERVER_ADDR", LocalAddr},   %% Apache compat
            {"LOCAL_ADDR", LocalAddr},    %% IIS compat
            {"QUERY_STRING", QueryString},
            {"CONTENT_TYPE", H#headers.content_type},
            {"CONTENT_LENGTH", H#headers.content_length},
            {"HTTP_ACCEPT", H#headers.accept},
            {"HTTP_USER_AGENT", H#headers.user_agent},
            {"HTTP_REFERER", H#headers.referer},
            {"HTTP_IF_MODIFIED_SINCE", H#headers.if_modified_since},
            {"HTTP_IF_MATCH", H#headers.if_match},
            {"HTTP_IF_NONE_MATCH", H#headers.if_none_match},
            {"HTTP_IF_UNMODIFIED_SINCE", H#headers.if_unmodified_since},
            {"HTTP_COOKIE", flatten_val(make_cookie_val(H#headers.cookie))}
           ]++lists:map(fun({http_header,_,Var,_,Val})->{tohttp(Var),Val} end,
                        H#headers.other)
          )) ++
        Extra_CGI_Vars.

tohttp(X) ->
    "HTTP_"++lists:map(fun tohttp_c/1, yaws:to_list(X)).


tohttp_c($-) ->
    $_;

tohttp_c(C) when C >= $a , C =< $z ->
    C - $a + $A;

tohttp_c(C) ->
    C.


make_cookie_val([]) ->
    undefined;
make_cookie_val([C]) ->
    C;
make_cookie_val([C|CS]) ->
    [make_cookie_val(CS), $; | C].


%%% Seems not to be necessary, but open_port documentation says that
%%% value has to be a string.

flatten_val(L) when is_list(L) ->
    lists:flatten(L);
flatten_val(X) ->
    X.


notslash($/) ->
    false;
notslash(_) ->
    true.


pathof(F) ->
    case lists:dropwhile(fun notslash/1, lists:reverse(F)) of
        "/" ->
            "/";
        [$/ | Tail] -> lists:reverse(Tail)
    end.


exeof(F) ->
    [$\., $/|lists:reverse(lists:takewhile(fun notslash/1, lists:reverse(F)))].


do_header(_Arg, "HTTP/1."++[_,_,N1,N2,N3|_], _) ->
    {status, list_to_integer([N1,N2,N3])};
do_header(Arg, Header, Data) when is_list(Header) ->
    {HdrLower, HdrVal} = do_lower_header(Header),
    do_header(Arg, {HdrLower, yaws:join_sep(HdrVal, ":"), Header}, Data);
do_header(_Arg, {"content-type", CT, _}, {partial_data, Data}) ->
    {streamcontent, CT, Data};
do_header(_Arg, {"content-type", CT, _}, {all_data, Data}) ->
    {content, CT, Data};
do_header(_Arg, {"status", [N1,N2,N3|_], _}, _) ->
    {status, list_to_integer([N1,N2,N3])};
do_header(_Arg, {_, _, Line}, _) ->
    {header, Line}.

do_lower_header(Header) ->
    [HdrName | HdrVal] = yaws:split_sep(Header, $:),
    HdrNmParts = [yaws:to_lower(H) || H <- yaws:split_sep(HdrName, $-)],
    {yaws:join_sep(HdrNmParts, "-"), HdrVal}.

get_resp(WorkerPid) ->
    get_resp([], WorkerPid).

get_resp(Hs, WorkerPid) ->
    receive
        {WorkerPid, header, H} ->
            ?Debug("~p~n", [{WorkerPid, header, H}]),
            get_resp([H|Hs], WorkerPid);
        {WorkerPid, all_data, Data} ->
            ?Debug("~p~n", [{WorkerPid, all_data, Data}]),
            {Hs, {all_data, Data}};
        {WorkerPid, partial_data, Data} ->
            ?Debug("~p~n", [{WorkerPid, partial_data, binary_to_list(Data)}]),
            {Hs, {partial_data, Data}};
        {WorkerPid, failure, Reason} ->
            ?Debug("~p~n", [{WorkerPid, failure, Reason}]),
            {failure, Reason};
        _Other ->
            ?Debug("~p~n", [_Other]),
            get_resp(Hs, WorkerPid)
    end.


get_opt(Key, List, Default) ->
    case lists:keysearch(Key, 1, List) of
        {value, {_Key, Val}} -> Val;
        _ -> Default
    end.


%%%==========================================================================
%%% Code specific to CGI
%%%==========================================================================

%%%  TO DO:  Handle failure and timeouts.

%%%  call_cgi calls the script `Scriptfilename' (full path).
%%%  If `Exefilename' is given, it is the executable to handle this,
%%%  otherwise `Scriptfilame' is assumed to be executable itself.
%%%
%%%  Corresponding to a URI of
%%%     `http://somehost/some/dir/script.cgi/path/info',
%%%  `Pathinfo' should be set to `/path/info'.

%%%  These functions can be used from a `.yaws' file.
%%%  Note however, that they usually generate stream content.

call_cgi(Arg, Scriptfilename) ->
    call_cgi(Arg, undefined, Scriptfilename, undefined, []).

call_cgi(Arg, Exefilename, Scriptfilename) ->
    call_cgi(Arg, Exefilename, Scriptfilename, undefined, []).

call_cgi(Arg, Exefilename, Scriptfilename, Pathinfo) ->
    call_cgi(Arg, Exefilename, Scriptfilename, Pathinfo, []).

call_cgi(Arg, Exefilename, Scriptfilename, Pathinfo, ExtraEnv) ->
    case Arg#arg.state of
        {cgistate, WorkerPid} ->
            case Arg#arg.cont of
                cgicont ->
                    handle_clidata(Arg, WorkerPid);
                undefined ->
                    ?Debug("Error while reading clidata: ~p~n",
                           [Arg#arg.clidata]),
                    %%  Error, what to do?
                    exit(normal)
            end;
        _ ->
            WorkerPid = cgi_start_worker(Arg, Exefilename, Scriptfilename,
                                      Pathinfo, ExtraEnv, get(sc)),
            handle_clidata(Arg, WorkerPid)
    end.


cgi_start_worker(Arg, Exefilename, Scriptfilename, Pathinfo, ExtraEnv, SC) ->
    ExeFN = case Exefilename of
                undefined -> exeof(Scriptfilename);
                "" -> exeof(Scriptfilename);
                FN -> FN
            end,
    PI = case Pathinfo of
             undefined -> Arg#arg.pathinfo;
             OK -> OK
         end,
    WorkerPid = proc_lib:spawn(?MODULE, cgi_worker,
                               [self(), Arg, ExeFN, Scriptfilename,
                                PI, ExtraEnv, SC]),
    WorkerPid.



cgi_worker(Parent, Arg, Exefilename, Scriptfilename, Pathinfo, ExtraEnv0, SC) ->
    ExtraEnv = lists:map(fun({K,V}) when is_binary(K), is_binary(V) ->
                                 {binary_to_list(K), binary_to_list(V)};
                            ({K,V}) when is_binary(K) ->
                                 {binary_to_list(K), V};
                            ({K,V}) when is_binary(V) ->
                                 {K, binary_to_list(V)};
                            (KV) -> KV
                         end, ExtraEnv0),
    Env = build_env(Arg, Scriptfilename, Pathinfo, ExtraEnv, SC),
    ?Debug("~p~n", [Env]),
    CGIPort = open_port({spawn, Exefilename},
                        [{env, Env},
                         {cd, pathof(Scriptfilename)},
                         exit_status,
                         binary]),
    cgi_pass_through_clidata(Parent, CGIPort),
    cgi_do_work(Parent, Arg, CGIPort).


cgi_pass_through_clidata(Parent, CGIPort) ->
    receive
        {Parent, clidata, Clidata} ->
            ?Debug("Got clidata ~p~n", [binary_to_list(Clidata)]),
            Parent ! {self(), clidata_receipt},
            CGIPort ! {self(), {command, Clidata}},
            cgi_pass_through_clidata(Parent, CGIPort);
        {Parent, end_of_clidata} ->
            ?Debug("End of clidata~n", []),
            ok
    end.


cgi_do_work(Parent, Arg, Port) ->
    cgi_header_loop(Parent, Arg, {start, Port}).


cgi_header_loop(Parent, Arg, S) ->
    Line = cgi_get_line(S),
    ?Debug("Line = ~p~n", [Line]),
    case Line of
        {failure, F} ->
            Parent ! {self(), failure, F};
        {[], T} ->
            case T of
                {middle, Data, Port} ->
                    Parent ! {self(), partial_data, Data},
                    receive
                        {Parent, stream_data} ->
                            cgi_data_loop(Arg#arg.pid, Port);
                        {Parent, no_data} ->
                            ok
                    end;
                {ending, Data, _} ->
                    Parent ! {self(), all_data, Data},
                    receive
                        {Parent, stream_data} ->
                            yaws_api:stream_chunk_end(Arg#arg.pid);
                        {Parent, no_data} ->
                            ok
                    end
            end;
        {H, T} ->
            Parent ! {self(), header, H},
            cgi_header_loop(Parent, Arg, T)
    end.


cgi_data_loop(Pid, Port) ->
    receive
        {Port, {data,Data}} ->
            ?Debug("~p~n", [{data, binary_to_list(Data)}]),
            yaws_api:stream_chunk_deliver_blocking(Pid, Data),
            cgi_data_loop(Pid, Port);
        {Port, {exit_status, _Status}} ->
            ?Debug("~p~n", [{exit_status, _Status}]),
            yaws_api:stream_chunk_end(Pid);
        _Other ->
            ?Debug("~p~n", [_Other]),
            cgi_data_loop(Pid, Port)
    end.



cgi_get_line({start, Port}) ->
    receive
        {Port, {data,Data}} ->
            cgi_get_line([], {middle, Data, Port});
        {Port, {exit_status, 0}} ->
            ?Debug("~p~n", [{exit_status, 0}]),
            cgi_get_line([], {ending, <<>>, Port});
        {Port, {exit_status, Status}} when Status /=0 ->
            ?Debug("~p~n", [{exit_status, Status}]),
            {failure, {exit_status, Status}};
        _Other ->
            ?Debug("~p~n", [_Other]),
            cgi_get_line({start, Port})
    end;
cgi_get_line(State) ->
    cgi_get_line([], State).

cgi_get_line(Acc, {S, <>, Port}) ->
    {lists:reverse(Acc), {S, Tail, Port}};
cgi_get_line(Acc, {S, <>,
                   Port}) ->
    {lists:reverse(Acc), {S, Tail, Port}};
cgi_get_line(Acc, {middle, <<>>, Port}) ->
    cgi_get_line(Acc, cgi_add_resp(<<>>, Port));
cgi_get_line(Acc, {middle, <>, Port}) ->
    %% We SHOULD test for CRLF.
    %% Would be easier without.
    cgi_get_line(Acc, cgi_add_resp(<>, Port));
cgi_get_line(Acc, {ending, <<>>, Port}) ->
    {lists:reverse(Acc), {ending, <<>>, Port}};
cgi_get_line(Acc, {S, <>, Port}) ->
    cgi_get_line([C|Acc], {S, Tail, Port}).


cgi_add_resp(Bin, Port) ->
    receive
        {Port, {data,Data}} ->
            {middle, <>, Port};
        {Port, {exit_status, _Status}} ->
            ?Debug("~p~n", [{exit_status, _Status}]),
            {ending, Bin, Port};
        _Other ->
            ?Debug("~p~n", [_Other]),
            cgi_add_resp(Bin, Port)
    end.


%%%===========================================================================
%%% Code specific to FastCGI
%%%===========================================================================

-define(FCGI_VERSION_1, 1).

-define(FCGI_TYPE_BEGIN_REQUEST, 1).
%%% Not needed yet
%%%-define(FCGI_TYPE_ABORT_REQUEST, 2).
-define(FCGI_TYPE_END_REQUEST, 3).
-define(FCGI_TYPE_PARAMS, 4).
-define(FCGI_TYPE_STDIN, 5).
-define(FCGI_TYPE_STDOUT, 6).
-define(FCGI_TYPE_STDERR, 7).
%%% Not needed yet
%%%-define(FCGI_TYPE_DATA, 8).
%%%-define(FCGI_TYPE_GET_VALUES, 9).
%%%-define(FCGI_TYPE_GET_VALUES_RESULT, 10).
-define(FCGI_TYPE_UNKNOWN_TYPE, 11).

fcgi_type_name(?FCGI_TYPE_BEGIN_REQUEST) -> "begin-request";
%%% Not needed yet
%%%fcgi_type_name(?FCGI_TYPE_ABORT_REQUEST) -> "abort-request";
fcgi_type_name(?FCGI_TYPE_END_REQUEST) -> "end-request";
fcgi_type_name(?FCGI_TYPE_PARAMS) -> "params";
fcgi_type_name(?FCGI_TYPE_STDIN) -> "stdin";
fcgi_type_name(?FCGI_TYPE_STDOUT) -> "stdout";
fcgi_type_name(?FCGI_TYPE_STDERR) -> "stderr";
%%% Not needed yet
%%%fcgi_type_name(?FCGI_TYPE_DATA) -> "data";
%%%fcgi_type_name(?FCGI_TYPE_GET_VALUES) -> "get_values";
%%%fcgi_type_name(?FCGI_TYPE_GET_VALUES_RESULT) -> "get_values_result";
fcgi_type_name(?FCGI_TYPE_UNKNOWN_TYPE) -> "unknown-type".

%%% The FCGI implementation does not support handling concurrent requests
%%% over a connection; it creates a separate connection for each
%%% request. Hence, all application records have the same request-id,
%%% namely 1.
%%%
-define(FCGI_REQUEST_ID_MANAGEMENT, 0).
-define(FCGI_REQUEST_ID_APPLICATION, 1).

-define(FCGI_DONT_KEEP_CONN, 0).
-define(FCGI_KEEP_CONN, 1).

-define(FCGI_ROLE_RESPONDER, 1).
-define(FCGI_ROLE_AUTHORIZER, 2).
-define(FCGI_ROLE_FILTER, 3).

-ifdef(debug).   % To avoid compile warning if debug is disabled.
fcgi_role_name(?FCGI_ROLE_RESPONDER) -> "responder";
fcgi_role_name(?FCGI_ROLE_AUTHORIZER) -> "authorizer";
fcgi_role_name(?FCGI_ROLE_FILTER) -> "filter";
fcgi_role_name(_) -> "?".
-endif.

-define(FCGI_STATUS_REQUEST_COMPLETE, 0).
-define(FCGI_STATUS_CANT_MPX_CONN, 1).
-define(FCGI_STATUS_OVERLOADED, 2).
-define(FCGI_STATUS_UNKNOWN_ROLE, 3).

fcgi_status_name(?FCGI_STATUS_REQUEST_COMPLETE) -> "request-complete";
fcgi_status_name(?FCGI_STATUS_CANT_MPX_CONN) -> "cannot-multiple-connection";
fcgi_status_name(?FCGI_STATUS_OVERLOADED) -> "overloaded";
fcgi_status_name(?FCGI_STATUS_UNKNOWN_ROLE) -> "unknown-role";
fcgi_status_name(_) -> "?".

%%% Amount of time (in milliseconds) allowed to connect to the application
%%% server.
%%%
-define(FCGI_CONNECT_TIMEOUT_MSECS, 10000).

%%% Amount of time (in milliseconds) allowed for data to arrive when
%%% reading the TCP connection to the application server.
%%%
-define(FCGI_READ_TIMEOUT_MSECS, 10000).

%%% TODO: Implement a configurable timeout which applies to the whole
%%% operation (as oposed to individual socket reads).

-record(fcgi_worker_state, {
            app_server_host,            % The hostname or IP address of
                                        % the application server
            app_server_port,            % The TCP port number of the
                                        % application server
            path_info,                  % The path info
            env,                        % All environment variables to be passed
                                        % to the application (incl the extras)
            keep_connection,            % Delegate close authority to the
                                        % application?
            trace_protocol,             % If true, log info messages for sent
                                        % and received FastCGI messages
            log_app_error,              % If true, log error messages for
                                        % application errors (stderr and
                                        % non-zero exit)
            role,                       % The role of the worker
                                        % (responder, authorizer, filter)
            parent_pid,                 % The PID of the parent process = the
                                        % Yaws worker process
            yaws_worker_pid,            % When doing chunked output, stream to
                                        % this Yaws worker.
            app_server_socket,          % The TCP socket to the FastCGI
                                        % application server
            stream_to_socket            % The TCP socket to the web browser
                                        % (stream chunked delivery to
                                        %  this socket)
        }).


call_fcgi_responder(Arg) ->
    call_fcgi_responder(Arg, []).

call_fcgi_responder(Arg, Options) ->
    call_fcgi(?FCGI_ROLE_RESPONDER, Arg, Options).


call_fcgi_authorizer(Arg) ->
    call_fcgi_authorizer(Arg, []).

call_fcgi_authorizer(Arg, Options) ->
    Out = call_fcgi(?FCGI_ROLE_AUTHORIZER, Arg, Options),
    case fcgi_is_access_allowed(Out) of
        true ->
            StrippedOut = strip_content_from_out(Out),
            {allowed, StrippedOut};
        false ->
            {denied, Out}
    end.


call_fcgi(Role, Arg, Options) ->
    case Arg#arg.state of
        {cgistate, WorkerPid} ->
            case Arg#arg.cont of
                cgicont ->
                    ?Debug("Call FastCGI: continuation~n", []),
                    handle_clidata(Arg, WorkerPid)
            end;
        _ ->
            ?Debug("Call FastCGI:~n"
                   "  Role = ~p (~s)~n"
                   "  Options = ~p~n"
                   "  Arg = ~p~n",
                   [Role, fcgi_role_name(Role),
                    Options,
                    Arg]),
            GlobalConf = get(gc),
            ServerConf = get(sc),
            WorkerPid = fcgi_start_worker(Role, Arg, GlobalConf, ServerConf,
              Options),
            handle_clidata(Arg, WorkerPid)
    end.


is_not_content({content, _MimeType, _Content}) -> false;
is_not_content({streamcontent, _MimeType, _Content}) -> false;
is_not_content(_) -> true.


strip_content_from_out(Out) ->
    lists:filter(fun is_not_content/1, Out).


fcgi_worker_fail(WorkerState, Reason) ->
    ParentPid = WorkerState#fcgi_worker_state.parent_pid,
    ParentPid ! {self(), failure, Reason},
    error_logger:error_msg("FastCGI failure: ~p~n", [Reason]),
    %% exit normally to avoid filling log with crash messages
    exit(normal).

fcgi_worker_fail_if(true, WorkerState, Reason) ->
    fcgi_worker_fail(WorkerState, Reason);
fcgi_worker_fail_if(_Condition, _WorkerState, _Reason) ->
    ok.

fcgi_start_worker(Role, Arg, GlobalConf, ServerConf, Options) ->
    proc_lib:spawn(?MODULE, fcgi_worker,
                   [self(), Role, Arg, GlobalConf, ServerConf, Options]).


fcgi_worker(ParentPid, Role, Arg, GlobalConf, ServerConf, Options) ->
    {DefaultSvrHost, DefaultSvrPort} =
        case ServerConf#sconf.fcgi_app_server of
            undefined ->
                {undefined, undefined};
            Else ->
                Else
        end,
    AppServerHost = get_opt(app_server_host, Options, DefaultSvrHost),
    AppServerPort = get_opt(app_server_port, Options, DefaultSvrPort),
    PreliminaryWorkerState = #fcgi_worker_state{parent_pid = ParentPid},
    fcgi_worker_fail_if(AppServerHost == undefined, PreliminaryWorkerState,
                        "app server host must be configured"),
    fcgi_worker_fail_if(AppServerPort == undefined, PreliminaryWorkerState,
                        "app server port must be configured"),
    PathInfo = get_opt(path_info, Options, Arg#arg.pathinfo),
    ScriptFileName = Arg#arg.fullpath,
    ExtraEnv = get_opt(extra_env, Options, []),
    Env = build_env(Arg, ScriptFileName, PathInfo, ExtraEnv, ServerConf),
    TraceProtocol = get_opt(trace_protocol, Options,
                            ?sc_fcgi_trace_protocol(ServerConf)),
    LogAppError = get_opt(log_app_error, Options,
                          ?sc_fcgi_log_app_error(ServerConf)),
    TcpOptions = yaws:gconf_nslookup_pref(GlobalConf),
    AppServerSocket =
        fcgi_connect_to_application_server(PreliminaryWorkerState,
                                           AppServerHost, AppServerPort,
                                           TcpOptions),
    ?Debug("Start FastCGI worker:~n"
           "  Role = ~p (~s)~n"
           "  AppServerHost = ~p~n"
           "  AppServerPort = ~p~n"
           "  PathInfo = ~p~n"
           "  ExtraEnv = ~p~n"
           "  TraceProtocol = ~p~n"
           "  LogAppStderr = ~p~n",
           [Role, fcgi_role_name(Role),
            AppServerHost,
            AppServerPort,
            PathInfo,
            ExtraEnv,
            TraceProtocol,
            LogAppError]),
    WorkerState = #fcgi_worker_state{
      app_server_host = AppServerHost,
      app_server_port = AppServerPort,
      path_info = PathInfo,
      env = Env,
      keep_connection = false,                % Currently hard-coded; make
                                              % configurable in the future?
      trace_protocol = TraceProtocol,
      log_app_error = LogAppError,
      role = Role,
      parent_pid = ParentPid,
      yaws_worker_pid = Arg#arg.pid,
      app_server_socket = AppServerSocket
     },
    fcgi_send_begin_request(WorkerState),
    fcgi_send_params(WorkerState, Env),
    fcgi_send_params(WorkerState, []),
    fcgi_pass_through_client_data(WorkerState),
    fcgi_header_loop(WorkerState),
    gen_tcp:close(AppServerSocket),
    ok.


fcgi_pass_through_client_data(WorkerState) ->
    ParentPid = WorkerState#fcgi_worker_state.parent_pid,
    receive
        {ParentPid, clidata, ClientData} ->
            ParentPid ! {self(), clidata_receipt},
            fcgi_send_stdin(WorkerState, ClientData),
            fcgi_pass_through_client_data(WorkerState);
        {ParentPid, end_of_clidata} ->
            fcgi_send_stdin(WorkerState, <<>>)
    end.


fcgi_connect_to_application_server(WorkerState, Host, Port, TcpOptions) ->
    Options = [binary, {packet, 0}, {active, false}, {nodelay, true} |
      TcpOptions],
    case yaws:tcp_connect(Host, Port, Options, ?FCGI_CONNECT_TIMEOUT_MSECS) of
        {error, Reason} ->
            fcgi_worker_fail(WorkerState,
                             {"connect to application server failed", Reason});
        {ok, Socket} ->
            Socket
    end.


fcgi_send_begin_request(WorkerState) ->
    %% Not needed yet -- keep_connection is currently hard-coded to false
    %%KeepConnection = WorkerState#fcgi_worker_state.keep_connection,
    %%Flags = case KeepConnection of
    %%            true -> ?FCGI_KEEP_CONN;
    %%            false -> ?FCGI_DONT_KEEP_CONN
    %%        end,
    Flags = ?FCGI_DONT_KEEP_CONN,
    Role = WorkerState#fcgi_worker_state.role,
    fcgi_send_record(WorkerState, ?FCGI_TYPE_BEGIN_REQUEST,
                     ?FCGI_REQUEST_ID_APPLICATION, <>).


fcgi_send_params(WorkerState, NameValueList) ->
    fcgi_send_record(WorkerState, ?FCGI_TYPE_PARAMS,
                     ?FCGI_REQUEST_ID_APPLICATION, NameValueList).


fcgi_send_stdin(WorkerState, Data) ->
    fcgi_send_record(WorkerState, ?FCGI_TYPE_STDIN,
                     ?FCGI_REQUEST_ID_APPLICATION, Data).


%%% Not needed yet
%%%
%%% fcgi_send_data(ParentPid, Socket, Data) ->
%%%     fcgi_send_record(ParentPid, Socket, ?FCGI_TYPE_DATA,
%%%                      ?FCGI_REQUEST_ID_APPLICATION, Data).


%%% Not needed yet
%%%
%%% fcgi_send_abort_request(ParentPid, Socket) ->
%%%     fcgi_send_record(ParentPid, Socket, ?FCGI_TYPE_ABORT_REQUEST,
%%%                      ?FCGI_REQUEST_ID_APPLICATION, <<>>).


fcgi_data_to_string(Data) ->
    fcgi_data_to_string("", 0, "", "", Data).

fcgi_data_to_string(LinesStr, Count, CharStr, HexStr, <<>>) ->
    if
        Count == 0 ->
            LinesStr;
        true ->
            Padding = lists:duplicate(16 - Count, $ ),
            LinesStr ++ "\n    " ++ CharStr ++ Padding ++ "  " ++ HexStr
    end;
fcgi_data_to_string(LinesStr, Count, CharStr, HexStr,
                    <>) ->
    Char = if
        (Byte >= $!) and (Byte =< $~) ->
            Byte;
        true ->
            $.
    end,
    Hex = io_lib:format("~2.16.0b ", [Byte]),
    if
        Count == 16 ->
            fcgi_data_to_string(LinesStr ++ "\n    " ++ CharStr ++ "  " ++
                                HexStr, 1, [Char], Hex, MoreData);
        true ->
            fcgi_data_to_string(LinesStr, Count + 1, CharStr ++ [Char],
                                HexStr ++ Hex, MoreData)
    end.


fcgi_trace_protocol(WorkerState, Action, Version, Type, RequestId,
                    ContentLength, PaddingLength, Reserved, ContentData,
                    PaddingData) ->
    Trace = WorkerState#fcgi_worker_state.trace_protocol,
    if
        Trace ->
            error_logger:info_msg(
                "~s FastCGI record:~n"
                "  version = ~p~n"
                "  type = ~p (~s)~n"
                "  request-id = ~p~n"
                "  content-length = ~p~n"
                "  padding-length = ~p~n"
                "  reserved = ~p~n"
                "  content-data = ~s~n"
                "  padding-data = ~s~n",
                [Action,
                 Version,
                 Type, fcgi_type_name(Type),
                 RequestId,
                 ContentLength,
                 PaddingLength,
                 Reserved,
                 fcgi_data_to_string(ContentData),
                 fcgi_data_to_string(PaddingData)]);
        true ->
            ok
    end.


fcgi_send_record(WorkerState, Type, RequestId, NameValueList) ->
    EncodedRecord = fcgi_encode_record(WorkerState, Type, RequestId,
                                       NameValueList),
    AppServerSocket = WorkerState#fcgi_worker_state.app_server_socket,
    case gen_tcp:send(AppServerSocket, EncodedRecord) of
        {error, Reason} ->
            fcgi_worker_fail(WorkerState,
                             {"send to application server failed", Reason});
        ok ->
            ok
    end.


fcgi_encode_record(WorkerState, Type, RequestId, NameValueList)
  when is_list(NameValueList) ->
    fcgi_encode_record(WorkerState, Type, RequestId,
                       fcgi_encode_name_value_list(NameValueList));

fcgi_encode_record(WorkerState, Type, RequestId, ContentData)
  when is_binary(ContentData), size(ContentData) > 65535  ->
    <> = ContentData,
    [fcgi_encode_record(WorkerState, Type, RequestId, Bin),
     fcgi_encode_record(WorkerState, Type, RequestId, Rest)];

fcgi_encode_record(WorkerState, Type, RequestId, ContentData)
  when is_binary(ContentData) ->
    Version = 1,
    ContentLength = size(ContentData),
    %% Add padding bytes (if needed) to content bytes to make
    %% content plus padding a multiple of 8 bytes.
    PaddingLength = if
                        ContentLength rem 8 == 0 ->
                            0;
                        true ->
                            8 - (ContentLength rem 8)
                    end,
    PaddingData = <<0:(PaddingLength * 8)>>,
    Reserved = 0,
    fcgi_trace_protocol(WorkerState, "Send", Version, Type, RequestId,
                        ContentLength, PaddingLength, Reserved,
                        ContentData, PaddingData),
    <>.


fcgi_encode_name_value_list(_NameValueList = []) ->
    <<>>;
fcgi_encode_name_value_list(_NameValueList = [{Name, Value} | Tail]) ->
    <<(fcgi_encode_name_value(Name,Value))/binary,
      (fcgi_encode_name_value_list(Tail))/binary>>.


fcgi_encode_name_value(Name, _Value = undefined) ->
    fcgi_encode_name_value(Name, "");
fcgi_encode_name_value(Name0, Value0) ->
    Name = unicode:characters_to_binary(Name0),
    Value = unicode:characters_to_binary(Value0),
    NameSize = byte_size(Name),
    %% If name size is < 128, encode it as one byte with the high bit clear.
    %% If the name size >= 128, encoded it as 4 bytes with the high bit set.
    NameSizeData = if
                       NameSize < 128 ->
                           <>;
                       true ->
                           <<(NameSize bor 16#80000000):32>>
                   end,
    %% Same encoding for the value size.
    ValueSize = byte_size(Value),
    ValueSizeData = if
                        ValueSize < 128 ->
                            <>;
                        true ->
                            <<(ValueSize bor 16#80000000):32>>
                    end,
    list_to_binary([<>, Name, Value]).


fcgi_header_loop(WorkerState) ->
    fcgi_header_loop(WorkerState, start).

fcgi_header_loop(WorkerState, LineState) ->
    Line = fcgi_get_line(WorkerState, LineState),
    ParentPid = WorkerState#fcgi_worker_state.parent_pid,
    case Line of
        {failure, Reason} ->
            ParentPid ! {self(), failure, Reason};
        {_EmptyLine = [], NewLineState} ->
            case NewLineState of
                {middle, Data} ->
                    case WorkerState#fcgi_worker_state.role of
                        ?FCGI_ROLE_AUTHORIZER ->
                            % For authorization we never stream to the client
                            fcgi_collect_all_data_loop(WorkerState, Data);
                        _ ->
                            ParentPid ! {self(), partial_data, Data},
                            receive
                                {ParentPid, stream_data} ->
                                    fcgi_stream_data_loop(WorkerState);
                                {ParentPid, no_data} ->
                                    ok
                            end
                    end;
                {ending, Data} ->
                    ParentPid ! {self(), all_data, Data},
                    receive
                        {ParentPid, stream_data} ->
                            yaws_api:stream_chunk_end(
                              WorkerState#fcgi_worker_state.yaws_worker_pid);
                        {ParentPid, no_data} ->
                            ok
                    end
            end;
        {Header, NewLineState} ->
            ParentPid ! {self(), header, Header},
            fcgi_header_loop(WorkerState, NewLineState)
    end.


fcgi_get_line(WorkerState, start) ->
    case fcgi_get_output(WorkerState) of
        {data, Data} ->
            fcgi_get_line(WorkerState, [], {middle, Data});
        {exit_status, 0} ->
            fcgi_get_line(WorkerState, [], {ending, <<>>});
        {exit_status, Status} when Status /=0 ->
            {failure, {exit_status, Status}}
    end;
fcgi_get_line(WorkerState, LineState) ->
    fcgi_get_line(WorkerState, [], LineState).

fcgi_get_line(_WorkerState, Acc, {State, <>}) ->
    {lists:reverse(Acc), {State, Tail}};
fcgi_get_line(_WorkerState, Acc, {State, <>}) ->
    {lists:reverse(Acc), {State, Tail}};
fcgi_get_line(WorkerState, Acc, {middle, <<>>}) ->
    fcgi_get_line(WorkerState, Acc, fcgi_add_resp(WorkerState, <<>>));
fcgi_get_line(WorkerState, Acc, {middle, <>}) ->
    fcgi_get_line(WorkerState, Acc, fcgi_add_resp(WorkerState,
                                                  <>));
fcgi_get_line(_WorkerState, Acc, {ending, <<>>}) ->
    {lists:reverse(Acc), {ending, <<>>}};
fcgi_get_line(WorkerState, Acc, {State, <>}) ->
    fcgi_get_line(WorkerState, [Char | Acc], {State, Tail}).


fcgi_add_resp(WorkerState, OldData) ->
    case fcgi_get_output(WorkerState) of
        {data, NewData} ->
            {middle, <>};
        {exit_status, _Status} ->
            {ending, OldData}
    end.


fcgi_stream_data_loop(WorkerState) ->
    YawsWorkerPid = WorkerState#fcgi_worker_state.yaws_worker_pid,
    case catch fcgi_get_output(WorkerState) of
        {data, Data} ->
            yaws_api:stream_chunk_deliver_blocking(YawsWorkerPid, Data),
            fcgi_stream_data_loop(WorkerState);
        {exit_status, _Status} ->
            yaws_api:stream_chunk_end(YawsWorkerPid);
        {'EXIT', _Reason} ->
            yaws_api:stream_chunk_end(YawsWorkerPid)
    end.


fcgi_collect_all_data_loop(WorkerState, Data) ->
    YawsWorkerPid = WorkerState#fcgi_worker_state.yaws_worker_pid,
    case fcgi_get_output(WorkerState) of
        {data, MoreData} ->
            NewData = <>,
            fcgi_collect_all_data_loop(WorkerState, NewData);
        {exit_status, _Status} ->
            ParentPid = WorkerState#fcgi_worker_state.parent_pid,
            ParentPid ! {self(), all_data, Data},
            receive
                {ParentPid, stream_data} ->
                    yaws_api:stream_chunk_end(YawsWorkerPid);
                {ParentPid, no_data} ->
                    ok
            end
    end.


fcgi_get_output(WorkerState) ->
    {Type, ContentData} = fcgi_receive_record(WorkerState),
    case Type of
        ?FCGI_TYPE_END_REQUEST ->
            <> = ContentData,
            fcgi_worker_fail_if(ProtStatus < ?FCGI_STATUS_REQUEST_COMPLETE,
                                WorkerState,
                                {"received unknown protocol status",
                                 ProtStatus}),
            fcgi_worker_fail_if(ProtStatus > ?FCGI_STATUS_UNKNOWN_ROLE,
                                WorkerState,
                                {"received unknown protocol status",
                                 ProtStatus}),
            if
                ProtStatus /= ?FCGI_STATUS_REQUEST_COMPLETE ->
                    error_logger:error_msg("FastCGI protocol error: ~p (~s)~n",
                                           [ProtStatus,
                                            fcgi_status_name(ProtStatus)]);
                true ->
                    ok
            end,
            if
                (AppStatus /= 0),
                (WorkerState#fcgi_worker_state.log_app_error) ->
                    error_logger:error_msg(
                      "FastCGI application non-zero exit status: ~p~n",
                      [AppStatus]);
                true ->
                    ok
            end,
            {exit_status, AppStatus};
        ?FCGI_TYPE_STDOUT ->
            {data, ContentData};
        ?FCGI_TYPE_STDERR ->
            if
                (ContentData /= <<>>),
                (WorkerState#fcgi_worker_state.log_app_error) ->
                    error_logger:error_msg(
                      "FastCGI application stderr output:~s~n",
                      [fcgi_data_to_string(ContentData)]);
                true ->
                    ok
            end,
            fcgi_get_output(WorkerState);
        ?FCGI_TYPE_UNKNOWN_TYPE ->
            <> = ContentData,
            fcgi_worker_fail(
              WorkerState,
              {"application did not understand record type we sent",
               UnknownType})
    end.


fcgi_receive_record(WorkerState) ->
    Header = fcgi_receive_binary(WorkerState, 8, ?FCGI_READ_TIMEOUT_MSECS),
    <> = Header,
    fcgi_worker_fail_if(Version /= 1, WorkerState,
                        {"received unsupported version", Version}),
    case Type of
        ?FCGI_TYPE_END_REQUEST ->
            fcgi_worker_fail_if(RequestId /= ?FCGI_REQUEST_ID_APPLICATION,
                                WorkerState,
                                {"unexpected request id", RequestId}),
            fcgi_worker_fail_if(ContentLength /= 8, WorkerState,
                                {"incorrect content length for end request",
                                 ContentLength}),
            ok;
        ?FCGI_TYPE_STDOUT ->
            fcgi_worker_fail_if(RequestId /= ?FCGI_REQUEST_ID_APPLICATION,
                                WorkerState,
                                {"unexpected request id", RequestId}),
            ok;
        ?FCGI_TYPE_STDERR ->
            fcgi_worker_fail_if(RequestId /= ?FCGI_REQUEST_ID_APPLICATION,
                                WorkerState,
                                {"unexpected request id", RequestId}),
            ok;
        ?FCGI_TYPE_UNKNOWN_TYPE ->
            fcgi_worker_fail_if(RequestId /= ?FCGI_REQUEST_ID_MANAGEMENT,
                                WorkerState,
                                {"unexpected request id", RequestId}),
            fcgi_worker_fail_if(ContentLength /= 8, WorkerState,
                                {"incorrect content length for unknown type",
                                 ContentLength}),
            ok;
        OtherType ->
            throw({"received unexpected type", OtherType})
    end,
    ContentData = case ContentLength of
                      0 ->
                          <<>>;
                      _ ->
                          fcgi_receive_binary(WorkerState, ContentLength,
                                              ?FCGI_READ_TIMEOUT_MSECS)
                  end,
    case PaddingLength of
        0 ->
            {Type, ContentData};
        _ ->
            PaddingData = fcgi_receive_binary(WorkerState, PaddingLength,
                                              ?FCGI_READ_TIMEOUT_MSECS),
            fcgi_trace_protocol(WorkerState, "Receive",
                                Version, Type, RequestId,
                                ContentLength, PaddingLength,
                                Reserved, ContentData,
                                PaddingData),
            {Type, ContentData}
    end.


fcgi_receive_binary(_WorkerState, Length, _Timeout) when Length == 0 ->
    <<>>;
fcgi_receive_binary(WorkerState, Length, Timeout) ->
    AppServerSocket = WorkerState#fcgi_worker_state.app_server_socket,
    case gen_tcp:recv(AppServerSocket, Length, Timeout) of
        {error, Reason} ->
            fcgi_worker_fail(WorkerState,
                             {"recv from application server failed", Reason});
        {ok, Data} ->
            Data
    end.


%%% Access is allowed if, and only if, the resonse from the authorizer
%%% running on the application server contains a 200 OK status. Any other
%%% status or absence of a status means access is denied.
%%%
fcgi_is_access_allowed([Head | Tail]) ->
    fcgi_is_access_allowed(Head) orelse fcgi_is_access_allowed(Tail);
fcgi_is_access_allowed({status, 200}) ->
    true;
fcgi_is_access_allowed(_AnythingElse) ->
    false.


%%% Look for headers of the form "Variable-VAR_NAME: var value"
%%%
fcgi_extract_variables([Head | Tail]) ->
    fcgi_extract_variables(Head) ++ fcgi_extract_variables(Tail);
fcgi_extract_variables({header, "Variable-" ++ Rest}) ->
    [fcgi_split_header(Rest)];
fcgi_extract_variables(_AnythingElse) ->
    [].


fcgi_split_header(Header) ->
    fcgi_split_header(name, [], [], Header).

fcgi_split_header(_, NameAcc, ValueAcc, "") ->
    {string:strip(lists:reverse(NameAcc)),
     string:strip(lists:reverse(ValueAcc))};
fcgi_split_header(name, NameAcc, ValueAcc, [$: | MoreStr]) ->
    fcgi_split_header(value, NameAcc, ValueAcc, MoreStr);
fcgi_split_header(name, NameAcc, ValueAcc, [Char | MoreStr]) ->
    fcgi_split_header(name, [Char | NameAcc], ValueAcc, MoreStr);
fcgi_split_header(value, NameAcc, ValueAcc, [Char | MoreStr]) ->
    fcgi_split_header(value, NameAcc, [Char | ValueAcc], MoreStr).
yaws-2.0.2/src/yaws_websockets.erl0000664000175000017500000013433412605311412014133 00000000000000%%%----------------------------------------------------------------------
%%% File    : yaws_websockets.erl
%%% Author  : Davide Marques 
%%% Purpose : support for WebSockets
%%% Created : 18 Dec 2009 by Davide Marques 
%%% Modified: extensively revamped in 2011 by J.D. Bothma 
%%%----------------------------------------------------------------------

-module(yaws_websockets).
-author('nesrait@gmail.com').
-author('jbothma@gmail.com').
-behaviour(gen_server).

-include("../include/yaws.hrl").
-include("../include/yaws_api.hrl").

-include_lib("kernel/include/file.hrl").


%% RFC 6455 section 7.4.1: Defined Status Codes
-define(WS_STATUS_NORMAL,           1000).
-define(WS_STATUS_PROTO_ERROR,      1002).
-define(WS_STATUS_ABNORMAL_CLOSURE, 1006).
-define(WS_STATUS_INVALID_PAYLOAD,  1007).
-define(WS_STATUS_MSG_TOO_BIG,      1009).
-define(WS_STATUS_INTERNAL_ERROR,   1011).


-record(state, {arg,
                opts,
                wsstate,
                cbinfo,
                cbstate,
                cbtype,
                timeout=infinity,
                wait_pong_frame=false,
                close_frame_received=false,
                close_timer,
                reason=normal}).

-record(cbinfo, {module,
                 init_fun,
                 terminate_fun,
                 open_fun,
                 msg_fun_1,
                 msg_fun_2,
                 info_fun}).

-export([start/3, send/2, close/2]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

%%%----------------------------------------------------------------------
%% API
%%%----------------------------------------------------------------------
start(Arg, CallbackMod, Opts) ->
    PrepdOpts = preprocess_opts(Opts),

    %% Do some checks on request headers before starting the WebSocket process:
    %%   o "Connection:" header field should contain "websocket"
    %%   o "Upgrade:" header field should contain "upgrade"
    %%   o "Origin:" header field should be valid
    case check_connection(query_header("connection", Arg#arg.headers)) of
        ok ->
            ok;
        error ->
            error_logger:error_msg("Invalid connection header", []),
            deliver_xxx(Arg#arg.clisock, 400),
            exit(normal)
    end,

    case check_upgrade(query_header("upgrade", Arg#arg.headers)) of
        ok ->
            ok;
        error ->
            error_logger:error_msg("Invalid upgrade header", []),
            deliver_xxx(Arg#arg.clisock, 400),
            exit(normal)
    end,
    OriginOpt = get_opts(origin, PrepdOpts),
    Origin    = get_origin_header(Arg#arg.headers),
    case check_origin(Origin, OriginOpt) of
        ok ->
            ok;
        error ->
            error_logger:error_msg("Expected origin ~p but found ~p",
                                   [OriginOpt, Origin]),
            deliver_xxx(Arg#arg.clisock, 403),
            exit(normal)
    end,

    %% Start websocket process
    OwnerPid =
        case gen_server:start(?MODULE, [Arg, CallbackMod, PrepdOpts], []) of
            {ok, Pid} ->
                Pid;
            {error, Reason1} ->
                error_logger:error_msg("Failed to start websocket process: ~p",
                                       [Reason1]),
                deliver_xxx(Arg#arg.clisock, 500),
                exit(normal)
        end,

    %% Change the controller process of the client socket
    CliSock = Arg#arg.clisock,
    Res = case yaws_api:get_sslsocket(CliSock) of
              {ok, SslSocket} ->
                  ssl:setopts(SslSocket, [{packet, raw}, {active, once}]),
                  ssl:controlling_process(SslSocket, OwnerPid);
              undefined ->
                  inet:setopts(CliSock, [{packet, raw}, {active, once}]),
                  gen_tcp:controlling_process(CliSock, OwnerPid)
          end,
    case Res of
        ok ->
            gen_server:cast(OwnerPid, ok);
        {error, Reason2} ->
            error_logger:error_msg("Failed to start websocket process: ~p",
                                   [Reason2]),
            gen_server:cast(OwnerPid, {stop, Reason2}),
            deliver_xxx(Arg#arg.clisock, 500)
    end,
    exit(normal).


send(#ws_state{}=WSState, {Type, Data}) ->
    do_send(WSState, {Type, Data});
send(#ws_state{}=WSState, #ws_frame{}=Frame) ->
    do_send(WSState, Frame);
send(Pid, {Type, Data}) ->
    gen_server:cast(Pid, {send, {Type, Data}});
send(Pid, #ws_frame{}=Frame) ->
    gen_server:cast(Pid, {send, Frame}).

close(#ws_state{}=WSState, Reason) ->
    do_close(WSState, Reason);
close(Pid, Reason) ->
    gen_server:cast(Pid, {close, Reason}).

%%%----------------------------------------------------------------------
%% gen_server functions
%%%----------------------------------------------------------------------
init([Arg, CbMod, Opts]) ->
    case get_opts(auto_fragment_message, Opts) of
        true ->
            AutoFrag = {true, get_opts(auto_fragment_threshold, Opts)},
            put(auto_fragment_message, AutoFrag);
        false ->
            put(auto_fragment_message, false)
    end,
    {CbType, FrameState, InitState} =
        case get_opts(callback, Opts) of
            {basic,    St} -> {basic, {none, <<>>}, St};
            {advanced, St} -> {advanced, undefined, St};
            _              -> {basic, {none, <<>>}, []}
        end,
    KeepAliveTout = case get_opts(keepalive, Opts) of
                        true  -> get_opts(keepalive_timeout, Opts);
                        false -> infinity
                    end,
    case get_callback_info(CbMod) of
        {ok, #cbinfo{init_fun=undefined}=CbInfo} ->
            {ok, #state{arg     = Arg,
                        opts    = Opts,
                        cbinfo  = CbInfo,
                        cbtype  = CbType,
                        cbstate = {FrameState,InitState},
                        timeout = KeepAliveTout}, KeepAliveTout};
        {ok, #cbinfo{init_fun=InitFun}=CbInfo} ->
            case CbMod:InitFun([Arg, InitState]) of
                {ok, InitState1} ->
                    {ok, #state{arg     = Arg,
                                opts    = Opts,
                                cbinfo  = CbInfo,
                                cbtype  = CbType,
                                cbstate = {FrameState,InitState1},
                                timeout = KeepAliveTout}, KeepAliveTout};
                {ok, InitState1, Timeout} ->
                    {ok, #state{arg     = Arg,
                                opts    = Opts,
                                cbinfo  = CbInfo,
                                cbtype  = CbType,
                                cbstate = {FrameState,InitState1},
                                timeout = KeepAliveTout}, Timeout};
                {error, Reason} ->
                    {stop, Reason}
            end;
        {error, Reason} ->
            {stop, Reason}
    end.


%% ----
%% Skip all sync requests
handle_call(_Req, _From, State) ->
    {reply, ok, State, State#state.timeout}.


%% ----
%% Send the handshake response
handle_cast(ok, #state{arg=Arg, cbinfo=CbInfo}=State) ->
    CliSock = Arg#arg.clisock,

    WSVersion = ws_version(Arg#arg.headers),
    WSKey     = get_nonce_header(Arg#arg.headers),
    if
        element(1, WSVersion) == unsupported_version ->
            error_logger:error_msg("Unsupported protocol version", []),
            deliver_xxx(CliSock, 400, ["Sec-WebSocket-Version: 13, 8"]),
            {stop, normal, State#state{reason={error, WSVersion}}};

        undefined == WSKey ->
            error_logger:error_msg("No key found", []),
            deliver_xxx(CliSock, 400),
            {stop, normal, State#state{reason={error, key_notfound}}};

        true ->
            Protocol = get_protocol_header(Arg#arg.headers),
            WSState  = #ws_state{sock      = CliSock,
                                 vsn       = WSVersion,
                                 frag_type = none},
            handshake(CliSock, WSKey, Protocol),

            case CbInfo#cbinfo.open_fun of
                undefined ->
                    {noreply, State#state{wsstate=WSState},
                     State#state.timeout};
                OpenFun ->
                    CbMod = CbInfo#cbinfo.module,
                    {FrameState, CbState} = State#state.cbstate,
                    case CbMod:OpenFun(WSState, CbState) of
                        {ok, CbState1} ->
                            {noreply,
                             State#state{wsstate=WSState,
                                         cbstate={FrameState,CbState1}},
                             State#state.timeout};
                        {error, Reason} ->
                            do_close(WSState, Reason),
                            {stop, normal, State#state{reason={error, Reason}}}
                    end
            end
    end;

%% ----
%% Stop the current websocket process. Used when an error occured during process
%% startup.
handle_cast({stop, Reason}, State) ->
    {stop, normal, State#state{reason={error,Reason}}};

%% Send a frame to the client
handle_cast({send, {Type, Data}}, #state{wsstate=WSState}=State) ->
    do_send(WSState, {Type, Data}),
    {noreply, State, State#state.timeout};
handle_cast({send, #ws_frame{}=Frame}, #state{wsstate=WSState}=State) ->
    do_send(WSState, Frame),
    {noreply, State, State#state.timeout};
handle_cast({close, Reason}, #state{wsstate=WSState}=State) ->
    do_close(WSState, Reason),
    {noreply, State, State#state.timeout};

%% Skip all other async messages
handle_cast(_Msg, State) ->
    {noreply, State, State#state.timeout}.


%% ----
%% Receive a TCP packet from the client
handle_info({tcp, Socket, FirstPacket},
            #state{wsstate=#ws_state{sock=Socket}}=State) ->
    handle_frames(FirstPacket, State);
handle_info({ssl, Socket, FirstPacket},
            #state{wsstate=#ws_state{sock={ssl, Socket}}}=State) ->
    handle_frames(FirstPacket, State);

%% Abnormal socket closure: only if no Close frame was received or sent.
handle_info({tcp_closed, Socket},
            #state{wsstate=#ws_state{sock=Socket}}=State) ->
    if
        State#state.close_frame_received == true orelse
        State#state.close_timer /= undefined ->
            {stop, normal, State};
        true ->
            handle_abnormal_closure(State)
    end;
handle_info({ssl_closed, Socket},
            #state{wsstate=#ws_state{sock={ssl, Socket}}}=State) ->
    if
        State#state.close_frame_received == true orelse
        State#state.close_timer /= undefined ->
            {stop, normal, State};
        true ->
            handle_abnormal_closure(State)
    end;


%% Ignore timeout if a Close frame was sent or received
handle_info(timeout, #state{close_frame_received=true}=State) ->
    {noreply, State};
handle_info(timeout, #state{close_timer=TRef}=State) when TRef /= undefined ->
    {noreply, State};

%% Keepalive timeout: send a ping frame and wait for any reply
handle_info(timeout, #state{wait_pong_frame=false}=State) ->
    error_logger:info_msg("Send ping frame", []),
    GracePeriod = get_opts(keepalive_grace_period, State#state.opts),
    do_send(State#state.wsstate, {ping, <<>>}),
    {noreply, State#state{wait_pong_frame=true}, GracePeriod};

%% Grace period timeout
handle_info(timeout, #state{wait_pong_frame=true}=State) ->
    error_logger:error_msg("endpoint gone away !", []),
    State1 = State#state{wait_pong_frame=false},
    case get_opts(drop_on_timeout, State1#state.opts) of
        true  -> handle_abnormal_closure(State1);
        false -> handle_callback_info(timeout, State1)
    end;

%% Close timeout: just shutdown the gen_server
handle_info(close, State) ->
    case State#state.close_timer of
        undefined -> ok;
        TRef      -> erlang:cancel_timer(TRef)
    end,
    {stop, normal, State};

%% All other messages
handle_info(Info, State) ->
    handle_callback_info(Info, State).


%% ----
terminate(_, #state{arg=Arg, cbinfo=CbInfo}=State) ->
    case CbInfo#cbinfo.terminate_fun of
        undefined ->
            ok;
        TerminateFun ->
            CbMod = CbInfo#cbinfo.module,
            {_, CbState} = State#state.cbstate,
            CbMod:TerminateFun(State#state.reason, CbState)
    end,
    CliSock = case State#state.wsstate of
                  undefined -> Arg#arg.clisock;
                  WSState   -> WSState#ws_state.sock
              end,
    if
        CliSock /= undefined ->
            case yaws_api:get_sslsocket(CliSock) of
                {ok, SslSocket} -> ssl:close(SslSocket);
                undefined       -> gen_tcp:close(CliSock)
            end;
        true ->
            ok
    end.


%% ----
code_change(_OldVsn, Data, _Extra) ->
    {ok, Data}.


%%%----------------------------------------------------------------------
%% internal functions
%%%----------------------------------------------------------------------
get_callback_info(Mod) ->
    case code:ensure_loaded(Mod) of
        {module, _} ->
            InitFun = case erlang:function_exported(Mod, init, 1) of
                          true  -> init;
                          false -> undefined
                      end,
            TerminateFun = case erlang:function_exported(Mod, terminate, 2) of
                               true  -> terminate;
                               false -> undefined
                           end,
            OpenFun = case erlang:function_exported(Mod, handle_open, 2) of
                          true  -> handle_open;
                          false -> undefined
                      end,
            MsgFun1 = case erlang:function_exported(Mod, handle_message, 1) of
                          true  -> handle_message;
                          false -> undefined
                      end,
            MsgFun2 = case erlang:function_exported(Mod, handle_message, 2) of
                          true  -> handle_message;
                          false -> undefined
                      end,
            InfoFun = case erlang:function_exported(Mod, handle_info, 2) of
                          true  -> handle_info;
                          false -> undefined
                      end,
            {ok, #cbinfo{module        = Mod,
                         init_fun      = InitFun,
                         terminate_fun = TerminateFun,
                         open_fun      = OpenFun,
                         msg_fun_1     = MsgFun1,
                         msg_fun_2     = MsgFun2,
                         info_fun      = InfoFun}};
        {error, Reason} ->
            error_logger:error_msg("Cannot load callback module '~p': ~p",
                                   [Mod, Reason]),
            {error, Reason}
    end.


preprocess_opts(GivenOpts) ->
    Fun = fun({Key, Default}, Opts) ->
                  case lists:keyfind(Key, 1, Opts) of
                      false -> [{Key, Default}|Opts];
                      _     -> Opts
                  end
          end,
    Defaults = [
                {origin,                  any},
                {callback,                basic},
                {max_frame_size,          16 * 1024 * 1024}, %% 16 MB
                {max_message_size,        16 * 1024 * 1024}, %% 16 MB
                {close_if_unmasked,       false},
                {auto_fragment_message,   false},
                {auto_fragment_threshold, 1024 * 1024},      %%  1 MB
                {close_timeout,           5000},             %%  5 secs
                {keepalive,               false},
                {keepalive_timeout,       30000},            %% 30 secs
                {keepalive_grace_period,  2000},             %%  2 secs
                {drop_on_timeout,         false}
               ],
    lists:foldl(Fun, GivenOpts, Defaults).


get_opts(Key, Opts) ->
    {Key, Value} = lists:keyfind(Key, 1, Opts),
    Value.

check_origin(_Origin, any)       -> ok;
check_origin(Actual,  Actual )   -> ok;
check_origin(_Actual, _Expected) -> error.

check_connection(undefined) ->
    error;
check_connection(Connection) ->
    Vals = yaws:split_sep(string:to_lower(Connection), $,),
    case lists:member("upgrade", Vals) of
        true  -> ok;
        false -> error
    end.

check_upgrade(undefined) ->
    error;
check_upgrade(Upgrade) ->
    Vals = yaws:split_sep(string:to_lower(Upgrade), $,),
    case lists:member("websocket", Vals) of
        true  -> ok;
        false -> error
    end.



handshake(CliSock, Key, _Protocol) ->
    AcceptHash = hash_nonce(Key),
    Handshake  = ["HTTP/1.1 101 Switching Protocols\r\n",
                  "Upgrade: websocket\r\n",
                  "Connection: Upgrade\r\n",
                  "Sec-WebSocket-Accept: ", AcceptHash , "\r\n",
                  "\r\n"],
    case yaws_api:get_sslsocket(CliSock) of
        {ok, SslSocket} -> ssl:send(SslSocket, Handshake);
        undefined       -> gen_tcp:send(CliSock, Handshake)
    end.


do_send(#ws_state{sock=undefined}, _) ->
    ok;
do_send(WSState, Messages) when is_list(Messages) ->
    [do_send(WSState, Msg) || Msg <- Messages],
    ok;
do_send(WSState, {Type, Data}) ->
    do_send(WSState, #ws_frame{opcode=Type, payload=Data});
do_send(#ws_state{sock=Socket}, #ws_frame{}=Frame) ->
    case yaws_api:get_sslsocket(Socket) of
        {ok, SslSocket} -> [ssl:send(SslSocket, F)  || F <- frames(Frame)];
        undefined       -> [gen_tcp:send(Socket, F) || F <- frames(Frame)]
    end.


%% Add this clause to be compatible with previous versions.
do_close(WSState, normal) ->
    do_close(WSState, ?WS_STATUS_NORMAL);
%% Special case for status=1006, do not send this close frame
do_close(_WSState, ?WS_STATUS_ABNORMAL_CLOSURE) ->
    ok;
do_close(_WSState, {?WS_STATUS_ABNORMAL_CLOSURE, _}) ->
    ok;
do_close(WSState, Status) when is_integer(Status) ->
    do_send(WSState, {close, <>});
do_close(WSState, {Status,Reason}) when is_integer(Status), is_binary(Reason) ->
    do_send(WSState, {close, <>});
do_close(WSState, _) ->
    Status = ?WS_STATUS_INTERNAL_ERROR,
    do_send(WSState, {close, <>}).


deliver_xxx(CliSock, Code) ->
    deliver_xxx(CliSock, Code, []).

deliver_xxx(CliSock, Code, Hdrs) ->
    Reply = ["HTTP/1.1 ",integer_to_list(Code), $\s,
             yaws_api:code_to_phrase(Code), "\r\n",
             "Connection: close\r\n",
             lists:flatmap(fun(X) -> X ++ "\r\n" end, Hdrs),
             "\r\n"],
    case yaws_api:get_sslsocket(CliSock) of
        {ok, SslSocket} -> ssl:send(SslSocket, Reply);
        undefined       -> gen_tcp:send(CliSock, Reply)
    end.


%% ----
handle_frames(FirstPacket, #state{wsstate=WSState, opts=Opts}=State) ->
    FrameInfos = unframe_active_once(WSState, FirstPacket, Opts),
    Result = case State#state.cbtype of
                 basic    -> basic_messages(FrameInfos, State);
                 advanced -> advanced_messages(FrameInfos, State)
             end,
    case Result of
        {ok, State1, Timeout} ->
            Last = lists:last(FrameInfos),
            {noreply, State1#state{wsstate=Last#ws_frame_info.ws_state,
                                  wait_pong_frame=false},
             Timeout};
        {stop, State1} ->
            case State1#state.close_frame_received of
                true  ->
                    {stop, normal, State1};
                false ->
                    Tout = get_opts(close_timeout, State1#state.opts),
                    TRef = erlang:send_after(Tout, self(), close),
                    {noreply, State1#state{close_timer=TRef}}
            end
    end.


handle_callback_info(Info, #state{cbinfo=CbInfo}=State) ->
    case CbInfo#cbinfo.info_fun of
        undefined ->
            {noreply, State, State#state.timeout};
        InfoFun ->
            {_, CbState} = State#state.cbstate,
            CbMod = CbInfo#cbinfo.module,
            Res   = CbMod:InfoFun(Info, CbState),
            case handle_callback_result(Res, State) of
                {ok, State1, Timeout} -> {noreply, State1, Timeout};
                {stop, State1}        -> {stop, normal, State1}
            end
    end.

handle_abnormal_closure(#state{wsstate=WSState}=State) ->
    %% The only way we should get here is due to an abnormal close. Section
    %% 7.1.5 of RFC 6455 specifies 1006 as the connection close code for
    %% abnormal closure. It's also described in section 7.4.1.
    CloseStatus    = ?WS_STATUS_ABNORMAL_CLOSURE,
    ClosePayload   = <>,
    CloseWSState   = WSState#ws_state{sock=undefined,frag_type=none},
    CloseFrameInfo = #ws_frame_info{fin         = 1,
                                    rsv         = 0,
                                    opcode      = close,
                                    masked      = 0,
                                    masking_key = <<>>,
                                    length      = 2,
                                    payload     = ClosePayload,
                                    data        = ClosePayload,
                                    ws_state    = CloseWSState},
    Result = case State#state.cbtype of
                 basic ->
                     basic_messages([CloseFrameInfo],
                                    State#state{wsstate=CloseWSState});
                 advanced ->
                     advanced_messages([CloseFrameInfo],
                                       State#state{wsstate=CloseWSState})
             end,
    case Result of
        {ok, State1, _} -> {stop, normal, State1};
        {stop, State1}  -> {stop, normal, State1}
    end.


%% ----
basic_messages(FrameInfos, State) ->
    basic_messages(FrameInfos, State, State#state.timeout).

basic_messages([], State, Tout) ->
    {ok, State, Tout};
basic_messages([FrameInfo|Rest],
               #state{cbinfo=CbInfo, cbstate={FrameState,CbState}}=State,
               Tout) ->
    case handle_message(FrameInfo, FrameState, State#state.opts) of
        {continue, FrameState1} ->
            basic_messages(Rest, State#state{cbstate={FrameState1,CbState}},
                           Tout);

        {message, Message} when State#state.close_timer /= undefined ->
            case Message of
                {close, _, _} ->
                    %% The server is waiting for the Close frame. We can stop it
                    %% now.
                    erlang:cancel_timer(State#state.close_timer),
                    {stop, State#state{close_frame_received=true}};
                _ ->
                    %% The server is waiting for the Close frame, all other
                    %% messages are ignored.
                    basic_messages(Rest, State, Tout)
            end;

        {message, {pong, Data}} ->
            do_send(State#state.wsstate, {pong, Data}),
            basic_messages(Rest, State, Tout);

        {message, Message} ->
            CbMod = CbInfo#cbinfo.module,
            Res = case CbInfo#cbinfo.msg_fun_2 of
                      undefined ->
                          MsgFun1 = CbInfo#cbinfo.msg_fun_1,
                          catch CbMod:MsgFun1(Message);
                      MsgFun2 ->
                          catch CbMod:MsgFun2(Message, CbState)
                  end,
            IsCloseFrame = case Message of
                               {close, _, _} -> true;
                               _             -> false
                           end,
            State1 = State#state{cbstate={{none, <<>>}, CbState},
                                 close_frame_received=IsCloseFrame},
            case handle_callback_result(Res, State1) of
                {ok, State2, _} when IsCloseFrame == true ->
                    %% The callback module must return a Close frame. If not, we
                    %% force the server to close the connection
                    {stop, State2};
                {ok, State2, Tout1} ->
                    basic_messages(Rest, State2, Tout1);
                {stop, State2} ->
                    {stop, State2}
            end;

        {error, Reason} ->
            do_close(State#state.wsstate, Reason),
            {stop, State#state{close_frame_received=true, reason=Reason}}
    end.


%% unfragmented text message
handle_message(#ws_frame_info{fin=1, opcode=text, data=Data}, {none, <<>>},
               _Opts) ->
    case unicode:characters_to_binary(Data, utf8, utf8) of
        Data -> {message, {text, Data}};
        _    -> {error, {?WS_STATUS_INVALID_PAYLOAD, <<"invalid utf-8">>}}
    end;

%% start of a fragmented text message
handle_message(#ws_frame_info{fin=0, opcode=text, data=Data}, {none, <<>>},
               _Opts) ->
    case unicode:characters_to_binary(Data, utf8, utf8) of
        Data ->
            {continue, {text, [Data], <<>>}};
        {incomplete,Dec,Rest} ->
            {continue, {text, [Dec],  Rest}};
        _ ->
            {error, {?WS_STATUS_INVALID_PAYLOAD, <<"invalid utf-8">>}}
    end;

%% non-final continuation of a fragmented text message
handle_message(#ws_frame_info{fin=0, data=Data, opcode=continuation},
               {text, Dec0, Rest0}, Opts) ->
    MaxLen = get_opts(max_message_size, Opts),
    Len    = iolist_size(Dec0) + byte_size(Rest0) + byte_size(Data),
    if
        Len > MaxLen ->
            {error, {?WS_STATUS_MSG_TOO_BIG, <<"Message too big">>}};
        true ->
            Data1 = <>,
            case unicode:characters_to_binary(Data1, utf8, utf8) of
                Data1 ->
                    {continue, {text, [Data1|Dec0], <<>>}};
                {incomplete, Dec1, Rest1} ->
                    {continue, {text, [Dec1|Dec0],  Rest1}};
                _ ->
                    {error, {?WS_STATUS_INVALID_PAYLOAD, <<"invalid utf-8">>}}
            end
    end;

%% end of text fragmented message
handle_message(#ws_frame_info{fin=1, opcode=continuation, data=Data},
               {text, Dec, Rest}, Opts) ->
    MaxLen = get_opts(max_message_size, Opts),
    Len    = iolist_size(Dec) + byte_size(Rest) + byte_size(Data),
    if
        Len > MaxLen ->
            {error, {?WS_STATUS_MSG_TOO_BIG, <<"Message too big">>}};
        true ->
            Data1 = <>,
            case unicode:characters_to_binary(Data1, utf8, utf8) of
                Data1 ->
                    Msg = list_to_binary(lists:reverse([Data1|Dec])),
                    {message, {text, Msg}};
                _ ->
                    {error, {?WS_STATUS_INVALID_PAYLOAD, <<"invalid utf-8">>}}
            end
    end;

%% unfragmented binary message
handle_message(#ws_frame_info{fin=1, opcode=binary, data=Data}, {none, <<>>},
               _Opts) ->
    {message, {binary, Data}};

%% start of a fragmented binary message
handle_message(#ws_frame_info{fin=0, opcode=binary, data=Data}, {none, <<>>},
               _Opts) ->
    {continue, {binary, Data}};

%% non-final continuation of a fragmented binary message
handle_message(#ws_frame_info{fin=0, data=Data, opcode=continuation},
               {binary, FragAcc}, Opts) ->
    MaxLen = get_opts(max_message_size, Opts),
    Len    = byte_size(FragAcc) + byte_size(Data),
    if
        Len > MaxLen ->
            {error, {?WS_STATUS_MSG_TOO_BIG, <<"Message too big">>}};
        true ->
            {continue, {binary, <>}}
    end;

%% end of binary fragmented message
handle_message(#ws_frame_info{fin=1, opcode=continuation, data=Data},
               {binary, FragAcc}, Opts) ->
    MaxLen = get_opts(max_message_size, Opts),
    Len    = byte_size(FragAcc) + byte_size(Data),
    if
        Len > MaxLen ->
            {error, {?WS_STATUS_MSG_TOO_BIG, <<"Message too big">>}};
        true ->
            Unfragged = <>,
            {message, {binary, Unfragged}}
    end;

handle_message(#ws_frame_info{opcode=ping, data=Data}, _Acc, _Opts) ->
    {message, {pong, Data}};

handle_message(#ws_frame_info{opcode=pong}, Acc, _Opts) ->
    %% A response to an unsolicited pong frame is not expected.
    %% http://tools.ietf.org/html/rfc6455#section-5.5.3
    {continue, Acc};

%% According to RFC 6455 section 5.4, control messages like close MAY be
%% injected in the middle of a fragmented message, which is why we pass FragType
%% and FragAcc along below. Whether any clients actually do this in practice, I
%% don't know.
handle_message(#ws_frame_info{opcode=close, length=Len,
                              data=Data, ws_state=WSState},
               _Acc, _Opts) ->
    case Len of
        0 ->
            {message, {close, ?WS_STATUS_NORMAL, <<>>}};
        1 ->
            {error, {?WS_STATUS_PROTO_ERROR, <<"protocol error">>}};
        _ ->
            <> = Data,
            case unicode:characters_to_binary(Msg, utf8, utf8) of
                Msg ->
                    {message, {close, check_close_code(Status, WSState), Msg}};
                _ ->
                    {error, {?WS_STATUS_INVALID_PAYLOAD, <<"invalid utf-8">>}}
            end
    end;

handle_message(#ws_frame_info{}, _Acc, _Opts) ->
    {error, {?WS_STATUS_PROTO_ERROR, <<"protocol error">>}};

handle_message({fail_connection, Status, Msg}, _State, _Tout) ->
    {error, {Status, Msg}}.



advanced_messages(FrameInfos, State) ->
    advanced_messages(FrameInfos, State, State#state.timeout).

advanced_messages([], State, Tout) ->
    {ok, State, Tout};
advanced_messages([FrameInfo|Rest], #state{close_timer=TRef}=State,
                  Tout) when TRef /= undefined ->
    case FrameInfo of
        #ws_frame_info{opcode=close} ->
            %% The server is waiting for the Close frame. We can stop it now.
            erlang:cancel_timer(TRef),
            {stop, State#state{close_frame_received=true}};
        _ ->
            %% The server is waiting for the Close frame, all other messages are
            %% ignored.
            advanced_messages(Rest, State, Tout)
    end;
advanced_messages([FrameInfo|Rest],
                  #state{cbinfo=CbInfo, cbstate={undefined,CbState}}=State,
                  _Tout) ->
    CbMod   = CbInfo#cbinfo.module,
    MsgFun2 = CbInfo#cbinfo.msg_fun_2,
    Res     = (catch CbMod:MsgFun2(FrameInfo, CbState)),
    IsCloseFrame = case FrameInfo of
                       #ws_frame_info{opcode=close} -> true;
                       _                            -> false
                   end,
    State1 = State#state{close_frame_received=IsCloseFrame},
    case handle_callback_result(Res, State1) of
        {ok, State2, _} when IsCloseFrame == true ->
            %% The callback module must return a Close frame. If not, we force
            %% the server to close the connection
            {stop, State2};
        {ok, State2, Tout1} ->
            advanced_messages(Rest, State2, Tout1);
        {stop, State2} ->
            {stop, State2}
    end.


%% The checks for close status codes here are based on RFC 6455 and on the
%% autobahn testsuite (http://autobahn.ws/testsuite).
check_close_code(Code, WSState) ->
    if
        Code >= 3000 andalso Code =< 4999 ->
            Code;
        Code < 1000 ->
            ?WS_STATUS_PROTO_ERROR;
        Code == 1006 andalso WSState#ws_state.sock == undefined ->
            Code;
        Code >= 1004 andalso Code =< 1006 ->
            ?WS_STATUS_PROTO_ERROR;
        Code > 1011 ->
            ?WS_STATUS_PROTO_ERROR;
        true ->
            Code
    end.


handle_callback_result({reply, Messages}, State) ->
    do_send(State#state.wsstate, Messages),
    {ok, State, State#state.timeout};
handle_callback_result({reply, Messages, CbState1}, State) ->
    do_send(State#state.wsstate, Messages),
    {FrameState, _} = State#state.cbstate,
    {ok, State#state{cbstate={FrameState, CbState1}}, State#state.timeout};
handle_callback_result({reply, Messages, CbState1, Timeout}, State) ->
    do_send(State#state.wsstate, Messages),
    {FrameState, _} = State#state.cbstate,
    {ok, State#state{cbstate={FrameState, CbState1}}, Timeout};

handle_callback_result(noreply, State) ->
    {ok, State, State#state.timeout};
handle_callback_result({noreply, CbState1}, State) ->
    {FrameState, _} = State#state.cbstate,
    {ok, State#state{cbstate={FrameState, CbState1}}, State#state.timeout};
handle_callback_result({noreply, CbState1, Timeout}, State) ->
    {FrameState, _} = State#state.cbstate,
    {ok, State#state{cbstate={FrameState, CbState1}}, Timeout};

handle_callback_result({close, Reason}, State) ->
    do_close(State#state.wsstate, Reason),
    case is_fatal_error(Reason) of
        true  -> {stop, State#state{close_frame_received=true, reason=Reason}};
        false -> {stop, State#state{reason=Reason}}
    end;
handle_callback_result({close, Reason, CbState1}, State) ->
    do_close(State#state.wsstate, Reason),
    {FrameState, _} = State#state.cbstate,
    State1 = State#state{cbstate={FrameState, CbState1}},
    case is_fatal_error(Reason) of
        true  -> {stop, State1#state{close_frame_received=true, reason=Reason}};
        false -> {stop, State1#state{reason=Reason}}
    end;
handle_callback_result({close, Reason, Messages, CbState1}, State) ->
    do_send(State#state.wsstate, Messages),
    do_close(State#state.wsstate, Reason),
    {FrameState, _} = State#state.cbstate,
    State1 = State#state{cbstate={FrameState, CbState1}},
    case is_fatal_error(Reason) of
        true  -> {stop, State1#state{close_frame_received=true, reason=Reason}};
        false -> {stop, State1#state{reason=Reason}}
    end;

handle_callback_result({'EXIT', Reason}, State) ->
    do_close(State#state.wsstate, ?WS_STATUS_INTERNAL_ERROR),
    {stop, State#state{close_frame_received=true, reason={error,Reason}}}.


is_fatal_error(?WS_STATUS_PROTO_ERROR)           -> true;
is_fatal_error({?WS_STATUS_PROTO_ERROR, _})      -> true;
is_fatal_error(?WS_STATUS_ABNORMAL_CLOSURE)      -> true;
is_fatal_error({?WS_STATUS_ABNORMAL_CLOSURE, _}) -> true;
is_fatal_error(?WS_STATUS_INVALID_PAYLOAD)       -> true;
is_fatal_error({?WS_STATUS_INVALID_PAYLOAD, _})  -> true;
is_fatal_error(?WS_STATUS_MSG_TOO_BIG)           -> true;
is_fatal_error({?WS_STATUS_MSG_TOO_BIG, _})      -> true;
is_fatal_error(?WS_STATUS_INTERNAL_ERROR)        -> true;
is_fatal_error({?WS_STATUS_INTERNAL_ERROR, _})   -> true;
is_fatal_error(_)                                -> false.


%% ----
ws_version(Headers) ->
    VersionVal = query_header("sec-websocket-version", Headers),
    case VersionVal of
        "8"  -> 8;
        "13" -> 13;
        V    -> {unsupported_version, V}
    end.

buffer(Socket, Len, Buffered) ->
    case Buffered of
        <<_Expected:Len/binary>> -> % exactly enough
            Buffered;
        <<_Expected:Len/binary,_Extra/binary>> -> % more than expected
            Buffered;
        _ ->
            %% not enough
            More = do_recv(Socket, Len - byte_size(Buffered), []),
            <>
    end.

do_recv(_, 0, Acc) ->
    list_to_binary(lists:reverse(Acc));
do_recv(Socket, Sz, Acc) ->
    %% TODO: add configurable timeout to receive data
    Res = case yaws_api:get_sslsocket(Socket) of
              {ok, SslSocket} -> ssl:recv(SslSocket, Sz,  5000);
              undefined       -> gen_tcp:recv(Socket, Sz, 5000)
          end,
    case Res of
        {ok, Bin}       -> do_recv(Socket, Sz - byte_size(Bin), [Bin|Acc]);
        {error, Reason} -> throw({tcp_error, Reason})
    end.


checks(Unframed) ->
    check_reserved_bits(Unframed).

check_control_frame(Len, Opcode, Fin) ->
    if
        (Len > 125) and (Opcode > 7) ->
            %% http://tools.ietf.org/html/rfc6455#section-5.5
            {fail_connection, ?WS_STATUS_PROTO_ERROR,
             <<"control frame > 125 bytes">>};
        (Fin == 0) and (Opcode > 7) ->
            {fail_connection, ?WS_STATUS_PROTO_ERROR,
             <<"control frame may not be fragmented">>};
        true ->
            ok
    end.

%% no extensions are supported yet
%% http://tools.ietf.org/html/rfc6455#section-5.2
check_reserved_bits(Unframed = #ws_frame_info{rsv=0}) ->
    check_reserved_opcode(Unframed);
check_reserved_bits(#ws_frame_info{rsv=RSV}) ->
    {fail_connection, ?WS_STATUS_PROTO_ERROR, <<"rsv bits were ", (RSV+48),
                              " but should be unset">>}.


check_reserved_opcode(#ws_frame_info{opcode = undefined}) ->
    {fail_connection, ?WS_STATUS_PROTO_ERROR, <<"Reserved opcode">>};
check_reserved_opcode(_) ->
    ok.


ws_frame_info(#ws_state{sock=Socket},
              <>,
              Opts) ->
    case check_control_frame(Len1, Opcode, Fin) of
        ok ->
            case ws_frame_info_secondary(Socket, Masked, Len1, Rest, Opts) of
                {ws_frame_info_secondary,Length,MaskingKey,Payload,Excess} ->
                    FrameInfo = #ws_frame_info{fin=Fin,
                                               rsv=Rsv,
                                               opcode=opcode_to_atom(Opcode),
                                               masked=Masked,
                                               masking_key=MaskingKey,
                                               length=Length,
                                               payload=Payload},
                    {FrameInfo, Excess};
                Else ->
                    Else
            end;
        Other ->
            Other
    end;

ws_frame_info(WSState = #ws_state{sock=Socket}, FirstPacket, Opts) ->
    ws_frame_info(WSState, buffer(Socket, 2, FirstPacket), Opts).


ws_frame_info_secondary(Socket, Masked, Len1, Rest, Opts) ->
    MaxLen = get_opts(max_frame_size, Opts),
    CloseIfUnmasked = get_opts(close_if_unmasked, Opts),
    MaskLength = case Masked of
                     0 -> 0;
                     1 -> 4
                 end,
    case Len1 of
        126 ->
            <> =
                buffer(Socket, MaskLength + 2 , Rest);
        127 ->
            <> =
                buffer(Socket, MaskLength + 8 , Rest);
        Len ->
            <> =
                buffer(Socket, MaskLength, Rest)
    end,
    if
        CloseIfUnmasked == true andalso MaskingKey == <<>> ->
            error_logger:error_msg("Unmasked frame forbidden", []),
            {fail_connection, ?WS_STATUS_PROTO_ERROR,
             <<"Unmasked frame forbidden">>};
        Len > MaxLen ->
            error_logger:error_msg(
              "Payload length ~p longer than max allowed of ~p",
              [Len, MaxLen]
             ),
            {fail_connection, ?WS_STATUS_MSG_TOO_BIG, <<"Frame too big">>};
        true ->
            <> = buffer(Socket, Len, Rest2),
            {ws_frame_info_secondary, Len, MaskingKey, Payload, Excess}
    end.

unframe_active_once(WSState, FirstPacket, Opts) ->
    Frames = unframe(WSState, FirstPacket, Opts),
    websocket_setopts(WSState, [{active, once}]),
    Frames.


%% Returns all the WebSocket frames fully or partially contained in FirstPacket,
%% reading exactly as many more bytes from Socket as are needed to finish
%% unframing the last frame partially included in FirstPacket, if needed.
%%
%% The length of this list and depth of this recursion is limited by the size of
%% your socket receive buffer.
%%
%% -> { #ws_state, [#ws_frame_info,...,#ws_frame_info] }
unframe(_WSState, <<>>, _Opts) ->
    [];
unframe(WSState, FirstPacket, Opts) ->
    case unframe_one(WSState, FirstPacket, Opts) of
        {FrameInfo = #ws_frame_info{ws_state = NewWSState}, RestBin} ->
            %% Every new recursion uses the #ws_state from the calling
            %% recursion.
            [FrameInfo | unframe(NewWSState, RestBin, Opts)];
        Fail ->
            [Fail]
    end.

%% -> {#ws_frame_info, RestBin} | {fail_connection, Reason}
unframe_one(WSState, FirstPacket, Opts) ->
    case catch ws_frame_info(WSState, FirstPacket, Opts) of
        {FrameInfo = #ws_frame_info{}, RestBin} ->
            Unmasked = mask(FrameInfo#ws_frame_info.masking_key,
                            FrameInfo#ws_frame_info.payload),
            case frag_state_machine(WSState, FrameInfo) of
                #ws_state{}=NewWSState ->
                    Unframed = FrameInfo#ws_frame_info{data     = Unmasked,
                                                       ws_state = NewWSState},
                    case checks(Unframed) of
                        ok   -> {Unframed, RestBin};
                        Else -> Else
                    end;
                Else ->
                    Else
            end;
        {tcp_error, Reason} ->
            %% FIXME: close the connection ?
            error_logger:error_msg("Abnormal Closure: ~p", [Reason]),
            CloseStatus    = ?WS_STATUS_ABNORMAL_CLOSURE,
            ClosePayload   = <>,
            CloseWSState   = WSState#ws_state{sock=undefined,frag_type=none},
            {#ws_frame_info{fin         = 1,
                            rsv         = 0,
                            opcode      = close,
                            masked      = 0,
                            masking_key = 0,
                            length      = 2,
                            payload     = ClosePayload,
                            data        = ClosePayload,
                            ws_state    = CloseWSState}, <<>>};
        Else ->
            Else
    end.

websocket_setopts(#ws_state{sock=Socket}, Opts) ->
    case yaws_api:get_sslsocket(Socket) of
        {ok, SslSocket} -> ssl:setopts(SslSocket, Opts);
        undefined       -> inet:setopts(Socket, Opts)
    end.

is_control_op(Op) ->
    atom_to_opcode(Op) > 7.

%% Unfragmented message
frag_state_machine(#ws_state{frag_type=none} = State,
                   #ws_frame_info{fin=1}) ->
    State;

%% Beginning of fragmented text message
frag_state_machine(#ws_state{frag_type=none} = State,
                   #ws_frame_info{fin=0, opcode=text}) ->
    State#ws_state{frag_type = text};

%% Beginning of fragmented binary message
frag_state_machine(#ws_state{frag_type=none} = State,
                   #ws_frame_info{fin=0, opcode=binary}) ->
    State#ws_state{frag_type = binary};

%% Expecting text continuation
frag_state_machine(#ws_state{frag_type=text} = State,
                   #ws_frame_info{fin=0, opcode=continuation}) ->
    State;

%% Expecting binary continuation
frag_state_machine(#ws_state{frag_type=binary}=State,
                   #ws_frame_info{fin=0, opcode=continuation}) ->
    State;

%% End of fragmented text message
frag_state_machine(#ws_state{frag_type=text} = State,
                   #ws_frame_info{fin=1, opcode=continuation}) ->
    State#ws_state{frag_type = none};

%% End of fragmented binary message
frag_state_machine(#ws_state{frag_type=binary} = State,
                   #ws_frame_info{fin=1, opcode=continuation}) ->
    State#ws_state{frag_type = none};


frag_state_machine(State, #ws_frame_info{opcode = Op}) ->
    IsControl = is_control_op(Op),
    if
        IsControl == true ->
            %% Control message never changes fragmentation state
            State;
        true ->
            %% Everything else is wrong
            {fail_connection, ?WS_STATUS_PROTO_ERROR,
             <<"fragmentation rules violated">>}
    end.


opcode_to_atom(16#0) -> continuation;
opcode_to_atom(16#1) -> text;
opcode_to_atom(16#2) -> binary;
opcode_to_atom(16#8) -> close;
opcode_to_atom(16#9) -> ping;
opcode_to_atom(16#A) -> pong;
opcode_to_atom(_)    -> undefined.

atom_to_opcode(continuation) -> 16#0;
atom_to_opcode(text)         -> 16#1;
atom_to_opcode(binary)       -> 16#2;
atom_to_opcode(close)        -> 16#8;
atom_to_opcode(ping)         -> 16#9;
atom_to_opcode(pong)         -> 16#A.


frames(#ws_frame{fin=true, opcode=C, payload=Payload}=Frame) when C == text;
                                                                  C == binary ->
    %% try auto-fragmentation only on unfragmented data frames
    case get(auto_fragment) of
        {true, Sz} when byte_size(Payload) > Sz ->
            <> = Payload,
            [frame(#ws_frame{fin=false, opcode=C, payload=Chunk}) |
             fragment_frame(
               #ws_frame{fin=false, opcode=continuation, payload=Rest}, Sz
              )];
        _ ->
            [frame(Frame)]
    end;
frames(Frame) ->
    [frame(Frame)].



frame(#ws_frame{}=Frame) ->
    Fin     = case Frame#ws_frame.fin of
                  true  -> 1;
                  false -> 0
              end,
    Rsv     = Frame#ws_frame.rsv,
    OpCode  = atom_to_opcode(Frame#ws_frame.opcode),
    Payload = Frame#ws_frame.payload,
    Length  = byte_size(Payload),
    if
        Length < 126 ->
            <>;
        Length < 65536 ->
            <>;
        true ->
            <>
    end.


fragment_frame(#ws_frame{payload=Payload}=Frame, Sz) ->
    case Payload of
        <<_:Sz/binary>> ->
            [frame(Frame#ws_frame{fin=true})];
        <> ->
            [frame(Frame#ws_frame{payload=Chunk})|
             fragment_frame(Frame#ws_frame{payload=Rest}, Sz)];
        _ ->
            [frame(Frame#ws_frame{fin=true})]
    end.


mask(MaskBin, Data) ->
    list_to_binary(rmask(MaskBin, Data)).

%% unmask == mask. It's XOR of the four-byte masking key.
rmask(_,<<>>) ->
    [<<>>];
rmask(<<>>, Data) ->
    [Data];
rmask(MaskBin = <>,
      <>) ->
    Masked = Mask bxor Data,
    MaskedRest = rmask(MaskBin, Rest),
    [<> | MaskedRest ];
rmask(<>, <>) ->
    Masked = Mask bxor Data,
    [<>];
rmask(<>, <>) ->
    Masked = Mask bxor Data,
    [<>];
rmask(<>, <>) ->
    Masked = Mask bxor Data,
    [<>].


%% Internal functions
get_origin_header(Headers) ->
    case query_header("origin", Headers) of
        undefined -> query_header("sec-websocket-origin", Headers);
        Origin    -> Origin
    end.

get_protocol_header(Headers) ->
    query_header("sec-websocket-protocol", Headers, "unknown").

get_nonce_header(Headers) ->
    query_header("sec-websocket-key", Headers).

query_header(HeaderName, Headers) ->
    query_header(HeaderName, Headers, undefined).

query_header(Header, Headers, Default) ->
    yaws_api:get_header(Headers, Header, Default).

-ifdef(HAVE_CRYPTO_HASH).
-define(CRYPTO_HASH(V), crypto:hash(sha,V)).
-else.
-define(CRYPTO_HASH(V), crypto:sha(V)).
-endif.

hash_nonce(Nonce) ->
    Salted = Nonce ++ "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
    HashBin = ?CRYPTO_HASH(Salted),
    base64:encode_to_string(HashBin).
yaws-2.0.2/src/yaws_html.erl0000664000175000017500000001704312605311412012723 00000000000000%%    -*- Erlang -*-
%%    File:        parse_html.erl
%%    Author:        Johan Bevemyr
%%    Created:        Tue Nov 25 20:53:36 2003
%%    Purpose:   Transform html to an erlang represention (ehtml)

-module('yaws_html').
-author('jb@bevemyr.com').

-export([parse/1,parse/2,h2e/1]).

parse(Name) ->
    {ok, B} = file:read_file(Name),
    h2e(binary_to_list(B)).

parse(Name,Out) ->
    {ok, B} = file:read_file(Name),
    case h2e(binary_to_list(B)) of
        {ehtml, [], Ehtml} ->
            Cont = io_lib:format("~p", [{ehtml, Ehtml}]),
            file:write_file(Out, Cont);
        Error ->
            Error
    end.

h2e(Input) ->
    Tokens = tokenize(Input, [], [], 1),
    parse(Tokens, {ehtml,[],0}, [], []).

%% parse(Tokens, Stack, Acc)

parse([], {T,A,_L}, [], Acc) ->
    {T, A, lists:reverse(Acc)};
parse([], {T,A,L}, [{CTag,CAcc}|Stack], Acc) ->
    io:format("Unterminated tag '~p' at line ~p\n", [T,L]),
    parse([], CTag, Stack, [{T,A,lists:reverse(Acc)}|CAcc]);
parse([{begin_tag,T,A,L}|Tokens], CTag, Stack, Acc) ->
    case tag_type(T) of
        leaf ->
            parse(Tokens, CTag, Stack, [{T,A}|Acc]);
        node ->
            parse(Tokens, {T,A,L}, [{CTag,Acc}|Stack],[])
    end;

parse([{end_tag,T,[],_L}|Tokens], {T,A,_}, [{CTag,CAcc}|Stack], Acc) ->
    E = case Acc of
            [Single] ->
                {T,A,Single};
            _ ->
                {T,A,lists:reverse(Acc)}
        end,
    parse(Tokens, CTag, Stack, [E|CAcc]);

parse([{end_tag,T1,[],L1}|Tokens], CTag = {T2,_A,L2}, Stack, Acc) ->
    case tag_type(T1) of
        leaf -> %% ignore
            parse(Tokens, CTag, Stack, Acc);
        node ->
            Msg = lists:flatten(io_lib:format(
                                  "expected ''  on line ~p, start "
                                  "tag at line: ~p", [T2,L1,L2])),
            {error, Msg}
    end;

parse([{data, Data, _Line}|Tokens], CTag, Stack, Acc) ->
    case skip_space(Data, 0) of
        {[], _} ->
            parse(Tokens, CTag, Stack, Acc);
        _ ->
            parse(Tokens, CTag, Stack, [Data|Acc])
    end.
%%

tag_type(p)          -> leaf;
tag_type(hr)         -> leaf;
tag_type(input)      -> leaf;
tag_type(base)       -> leaf;
tag_type(img)        -> leaf;
tag_type('!doctype') -> leaf;
tag_type(meta)       -> leaf;
tag_type(link)       -> leaf;
tag_type(br)         -> leaf;
tag_type(_)          -> node.

%% tokenize(Input, DataAcc, TokenAcc, LineNr)

tokenize([], [], Tokens, _Line) ->
    lists:reverse(Tokens);
tokenize([], Acc, Tokens, Line) ->
    lists:reverse([{data, lists:reverse(Acc), Line}|Tokens]);
tokenize([$<,$!,$-,$-|R0], Acc, Tokens, L0) ->
    {R1, L1} = skip_comment(R0,L0),
    tokenize(R1, Acc, Tokens, L1);
tokenize([$<|R0], Acc, Tokens, L0) ->
    {Tag,R1,L1} = scan_tag(R0,L0),
    if
        Acc == [] ->
            next_token(Tag, R1, [Tag|Tokens], L1);
        true ->
            Data = {data,lists:reverse(Acc),L0},
            next_token(Tag, R1, [Tag,Data|Tokens], L1)
    end;
tokenize([C=$\n|R0], Acc, Tokens, L) ->
    tokenize(R0, [C|Acc], Tokens, L+1);
tokenize([C=$\r|R0], Acc, Tokens, L) ->
    tokenize(R0, [C|Acc], Tokens, L+1);
tokenize([C|R0], Acc, Tokens, L) ->
    tokenize(R0, [C|Acc], Tokens, L).

%%

next_token({begin_tag, script, _, _}, R, Tokens, L) ->
    {Data, R1, L1} = scan_endtag(R, "script", L),
    tokenize(R1, [], [{data, Data, L}|Tokens], L1);
next_token({begin_tag, style, _, _}, R, Tokens, L) ->
    {Data, R1, L1} = scan_endtag(R, "style", L),
    tokenize(R1, [], [{data, Data, L}|Tokens], L1);
next_token(_Tag, R, Tokens, L) ->
    tokenize(R, [], Tokens, L).

%% '<'  + [*['=']]* ['/'] '>'

scan_tag([$/|I], L) ->
    {_R0,L0} = skip_space(I, L),
    {Name,R1,L1} = scan_tag_name(I, L0),
    {R2,L2} = skip_space(R1, L1),
    {Args,R3,L3} = scan_tag_args(R2, L2),
    {{end_tag,list_to_atom(lowercase(Name)),Args,L0}, R3, L3};
scan_tag(I, L) ->
    {_R0,L0} = skip_space(I, L),
    {Name,R1,L1} = scan_tag_name(I, L0),
    {R2,L2} = skip_space(R1, L1),
    {Args,R3,L3} = scan_tag_args(R2, L2),
    {{begin_tag,list_to_atom(lowercase(Name)),Args,L0}, R3, L3}.

%%

scan_tag_name(I, L) ->
    scan_token(I, [], L).

%%

scan_tag_args(I, L) ->
    scan_tag_args(I, [], L).

scan_tag_args([], Acc, L) ->
    {lists:reverse(Acc), [], L};
scan_tag_args([$>|R], Acc, L) ->
    {lists:reverse(Acc), R, L};
scan_tag_args(R=[$<|_], Acc, L) ->  %%%% bad html
    {lists:reverse(Acc), R, L};
scan_tag_args(R0, Acc, L0) ->
    {Name,R1,L1} = scan_value(R0, L0),
    {R2, L2} = skip_space(R1, L1),
    case R2 of
        [$=|R3] ->
            {R4,L4} = skip_space(R3, L2),
            {Value,R5,L5} = scan_value(R4, L4),
            {R6,L6} = skip_space(R5, L5),
            OptName = list_to_atom(lowercase(Name)),
            scan_tag_args(R6, [{OptName,Value}|Acc], L6);
        _ ->
            scan_tag_args(R2, [Name|Acc], L2)
    end.

%%

scan_value([$"|R], L) ->
    scan_quote(R, [], $", L);
scan_value([$'|R], L) ->
    scan_quote(R, [], $', L);
scan_value(R, L) ->
    scan_token(R, [], L).

%%

scan_token([], Acc, L) ->
    {lists:reverse(Acc), [], L};
scan_token(R=[$>|_], Acc, L) ->
    {lists:reverse(Acc), R, L};
scan_token(R=[$<|_], Acc, L) ->  %%% bad html
    {lists:reverse(Acc), R, L};
scan_token(R=[$=|_], Acc, L) ->  %% bad html
    {lists:reverse(Acc), R, L};
scan_token([C|R], Acc, L0) ->
    case char_class(C) of
        space ->
            {lists:reverse(Acc), R, L0};
        nl ->
            {lists:reverse(Acc), R, L0+1};
        _ ->
            scan_token(R, [C|Acc], L0)
    end.

%%

scan_quote([], Acc, _Q, L) ->
    {lists:reverse(Acc), [], L};
scan_quote([Q|R], Acc, Q, L) ->
    {lists:reverse(Acc), R, L};
scan_quote([C=$\n|R], Acc, Q, L) ->
    scan_quote(R, [C|Acc], Q, L+1);
scan_quote([C=$\r|R], Acc, Q, L) ->
    scan_quote(R, [C|Acc], Q, L+1);
scan_quote([C|R], Acc, Q, L) ->
    scan_quote(R, [C|Acc], Q, L).

%%

scan_endtag(R, Tag, L) ->
    scan_endtag(R, Tag, [], L).

scan_endtag([], _Tag, Acc, L) ->
    {lists:reverse(Acc), [], L};
scan_endtag(R=[$<,$/|R0], Tag, Acc, L0) ->
    case casecmp(Tag, R0) of
        {true, R1} ->
            {R2,_} = skip_space(R1,L0),
            if hd(R2) == $> ->
                    {lists:reverse(Acc), R, L0};
               true ->
                    scan_endtag(R0, Tag, Acc, L0)
            end;
        false ->
            scan_endtag(R0, Tag, Acc, L0)
    end;
scan_endtag([C=$\n|R], Tag, Acc, L) ->
    scan_endtag(R, Tag, [C|Acc], L+1);
scan_endtag([C=$\r|R], Tag, Acc, L) ->
    scan_endtag(R, Tag, [C|Acc], L+1);
scan_endtag([C|R], Tag, Acc, L) ->
    scan_endtag(R, Tag, [C|Acc], L).

%%

casecmp([], R) -> {true, R};
casecmp([C1|T1], [C2|T2]) ->
    C2low = lowercase_ch(C2),
    if C1 == C2low -> casecmp(T1,T2);
       true        -> false
    end.

%%

char_class($\n) -> nl;
char_class($\r) -> nl;
char_class($ )  -> space;
char_class($\t) -> space;
char_class(C) when C >= $a, C =< $z -> alpha;
char_class(C) when C >= $A, C =< $Z -> alpha;
char_class(C) when C >= $0, C =< $9 -> digit;
char_class(_C)   -> other.

%%

skip_space([], L) ->
    {[], L};
skip_space(R = [C|R0], L) ->
    case char_class(C) of
        nl ->
            skip_space(R0, L+1);
        space ->
            skip_space(R0, L);
        _ ->
            {R, L}
    end.

%%

skip_comment([], L) ->          {[], L};
skip_comment([$-,$-,$>|R],L) -> {R,L};
skip_comment([$\n|R],L) ->      skip_comment(R,L+1);
skip_comment([$\r|R],L) ->      skip_comment(R,L+1);
skip_comment([_C|R],L) ->        skip_comment(R,L).

%%

lowercase(Str) ->
    [lowercase_ch(S) || S <- Str].

lowercase_ch(C) when C>=$A, C=<$Z -> C + 32;
lowercase_ch(C) -> C.
yaws-2.0.2/src/mime_type_c.erl0000664000175000017500000002254412605311412013210 00000000000000%%%----------------------------------------------------------------------
%%% File    : mime_type_c.erl
%%% Author  : Claes Wikstrom 
%%% Purpose :
%%% Created : 10 Jul 2002 by Claes Wikstrom 
%%%----------------------------------------------------------------------

-module(mime_type_c).
-author('klacke@hyber.org').

-export([generate/0, generate/3]).

-include("../include/yaws.hrl").
-include("yaws_charset.hrl").


-define(MIME_TYPES_FILE, filename:join(yaws:get_priv_dir(), "mime.types")).
-define(DEFAULT_MIME_TYPE, "text/plain").

%% This function is used during Yaws' compilation. To rebuild/reload mime_types
%% module, generate/3 _MUST_ be used.
generate() ->
    AppDir = yaws:get_app_dir(),
    GInfo  = #mime_types_info{
                mime_types_file = filename:join(AppDir, "priv/mime.types"),
                default_charset = ?YAWS_CHARSET
               },
    ModFile = filename:join(AppDir,  "src/mime_types.erl"),

    case generate(ModFile, GInfo, []) of
        ok ->
            erlang:halt(0);
        {error, Reason} ->
            error_logger:format("Cannot write module ~p: ~p\n",
                                [ModFile, file:format_error(Reason)]),
            erlang:halt(1)
    end.


%% GInfo      ::= #mime_types_info{}
%% SInfoMap   ::= [{{ServerName, Port}, #mime_types_info{}}]
%% ServerName ::= string() | atom()
generate(ModFile, GInfo, SInfoMap) ->
    case file:open(ModFile, [write]) of
        {ok, Fd} ->
            TypesData = [create_mime_types_data(Name, Info) ||
                            {Name, Info} <- [{global, GInfo}|SInfoMap] ],

            %% Generate module Header
            IncDir  = yaws:get_inc_dir(),
            IncFile = filename:join(IncDir, "yaws.hrl"),
            Include = "-include(\""++IncFile++"\").",
            io:format(Fd,
                      "-module(mime_types).~n~n"
                      "-export([default_type/0, default_type/1]).~n"
                      "-export([t/1, revt/1]).~n"
                      "-export([t/2, revt/2]).~n~n"
                      "~s~n~n", [Include]),


            %% Generate default_type/0, t/1 and revt/1
            io:format(Fd,
                      "default_type() -> default_type(global).~n"
                      "t(Ext) -> t(global, Ext).~n"
                      "revt(Ext) -> revt(global, Ext).~n~n", []),

            %% Generate default_type/1
            io:format(Fd, "default_type(#sconf{servername=SN, port=P}) -> "
                      "default_type({SN,P});~n", []),
            lists:foreach(fun({Name, _, DefaultType, DefaultCharset}) ->
                                  generate_default_type(Fd, Name, DefaultType,
                                                        DefaultCharset)
                          end, TypesData),
            io:format(Fd, "default_type(_) -> default_type(global).~n~n", []),

            %% Generate t/2 function
            io:format(Fd, "t(#sconf{servername=SN, port=P}, Ext) -> "
                      "t({SN,P}, Ext);~n", []),
            lists:foreach(fun({Name, MimeTypes, DefaultType, DefaultCharset}) ->
                                  generate_t(Fd, Name, MimeTypes,
                                             DefaultType, DefaultCharset)
                          end, TypesData),
            io:format(Fd, "t(_, Ext) -> t(global, Ext).~n~n", []),

            %% Generate revt/2 function
            io:format(Fd,
                      "revt(#sconf{servername=SN, port=P}, Ext) -> "
                      "revt({SN,P}, Ext);~n",
                      []),
            lists:foreach(fun({Name, MimeTypes, DefaultType, DefaultCharset}) ->
                                  generate_revt(Fd, Name, MimeTypes,
                                                DefaultType, DefaultCharset)
                          end, TypesData),
            io:format(Fd, "revt(_, RExt) -> revt(global, RExt).~n", []),

            file:close(Fd),
            ok;

        {error, Reason} ->
            {error, Reason}
    end.


%% ----
create_mime_types_data(Name, Info) ->
    Charsets = Info#mime_types_info.charsets,
    DefaultC = case Info#mime_types_info.default_charset of
                   undefined -> "";
                   DCharset  -> "; charset=" ++ DCharset
               end,

    Map = case Info#mime_types_info.mime_types_file of
              undefined -> read_mime_types_file(?MIME_TYPES_FILE);
              File      -> read_mime_types_file(File)
          end,
    TypesData =
        lists:foldl(fun({Ext, MimeType}, Acc) ->
                            ExtType = get_ext_type(Ext),
                            Charset = case lists:keyfind(Ext, 1, Charsets) of
                                          {_,C} ->
                                              "; charset=" ++ C;
                                          false ->
                                              case MimeType of
                                                  "text/"++_ -> DefaultC;
                                                  _          -> ""
                                              end
                                      end,
                            lists:keystore(Ext, 1, Acc,
                                           {Ext, ExtType, MimeType, Charset})
                    end, [], Map ++ Info#mime_types_info.types),
    {Name, TypesData, Info#mime_types_info.default_type, DefaultC}.


%% ----
generate_default_type(Fd, Name, DefaultType, DefaultCharset) ->
    io:format(Fd, "default_type(~p) -> \"~s~s\";~n",
              [Name, DefaultType, DefaultCharset]).


%% ----
generate_t(Fd, Name, [], "text/"++_=DefaultType, DefaultCharset) ->
    io:format(Fd, "t(~p, _) -> {regular, \"~s~s\"};~n",
              [Name, DefaultType, DefaultCharset]);
generate_t(Fd, Name, [], DefaultType, _) ->
    io:format(Fd, "t(~p, _) -> {regular, \"~s\"};~n", [Name, DefaultType]);
generate_t(Fd, Name, [{Ext,ExtType,MimeType,Charset}|Rest],
           DefaultType, DefaultCharset) ->
    case string:to_upper(Ext) of
        Ext ->
            io:format(Fd, "t(~p, ~p) -> {~p, \"~s~s\"};~n",
                      [Name, Ext, ExtType, MimeType, Charset]);
        UExt ->
            io:format(Fd,
                      "t(~p, ~p) -> {~p, \"~s~s\"};~n"
                      "t(~p, ~p) -> {~p, \"~s~s\"};~n",
                      [Name, Ext, ExtType, MimeType, Charset,
                       Name, UExt, ExtType, MimeType, Charset])
    end,
    generate_t(Fd, Name, Rest, DefaultType, DefaultCharset).


%% ----
generate_revt(Fd, Name, [], "text/"++_=DefaultType, DefaultCharset) ->
    io:format(Fd,
              "revt(~p, RExt) -> {regular, lists:reverse(RExt), \"~s~s\"};~n",
              [Name, DefaultType, DefaultCharset]);
generate_revt(Fd, Name, [], DefaultType, _) ->
    io:format(Fd,
              "revt(~p, RExt) -> {regular, lists:reverse(RExt), \"~s\"};~n",
              [Name, DefaultType]);
generate_revt(Fd, Name, [{Ext,ExtType,MimeType,Charset}|Rest],
           DefaultType, DefaultCharset) ->
    RExt = lists:reverse(Ext),
    case string:to_upper(Ext) of
        Ext ->
            io:format(Fd,
                      "revt(~p, ~p) -> {~p, ~p, \"~s~s\"};~n",
                      [Name, RExt, ExtType, Ext, MimeType, Charset]);
        UExt ->
            RUExt = lists:reverse(UExt),
            io:format(Fd,
                      "revt(~p, ~p) -> {~p, ~p, \"~s~s\"};~n"
                      "revt(~p, ~p) -> {~p, ~p, \"~s~s\"};~n",
                      [Name, RExt, ExtType, Ext, MimeType, Charset,
                       Name, RUExt, ExtType, UExt, MimeType, Charset])
    end,
    generate_revt(Fd, Name, Rest, DefaultType, DefaultCharset).

%% ----
read_mime_types_file(File) ->
    case file:open(File, [read]) of
        {ok, Io} ->
            %% Define mime-types for special extensions. It could be overridden
            Acc0 = [{E, "text/html"} || E <- get_special_exts()],
            read_mime_types_file(Io, 1, file:read_line(Io), Acc0);
        {error, Reason} ->
            error_logger:format("Cannot read ~p: ~p\n",
                                [File, file:format_error(Reason)]),
            []
    end.

read_mime_types_file(Io, _, eof, Acc) ->
    file:close(Io),
    lists:reverse(Acc);
read_mime_types_file(Io, Lno, {error, Reason}, Acc) ->
    file:close(Io),
    error_logger:format("read mime-types config failed at line ~p: ~p\n",
                        [Lno, file:format_error(Reason)]),
    lists:reverse(Acc);
read_mime_types_file(Io, Lno, {ok, [$#|_]}, Acc) ->
    read_mime_types_file(Io, Lno+1, file:read_line(Io), Acc);
read_mime_types_file(Io, Lno, {ok, [$\s|_]}, Acc) ->
    read_mime_types_file(Io, Lno+1, file:read_line(Io), Acc);
read_mime_types_file(Io, Lno, {ok, Line}, Acc0) ->
    case string:tokens(Line,"\r\n\s\t\0\f") of
        []  ->
            read_mime_types_file(Io, Lno+1, file:read_line(Io), Acc0);
        [_] ->
            read_mime_types_file(Io, Lno+1, file:read_line(Io), Acc0);
        [MimeType | Exts] ->
            Acc1 = lists:foldl(fun(Ext, Acc) ->
                                       lists:keystore(Ext, 1, Acc,
                                                      {Ext, MimeType})
                               end, Acc0, Exts),
            read_mime_types_file(Io, Lno+1, file:read_line(Io), Acc1)
    end.


%% ----
get_special_exts() -> ["yaws", "php", "cgi", "fcgi"].

get_ext_type("yaws") -> yaws;
get_ext_type("php")  -> php;
get_ext_type("cgi")  -> cgi;
get_ext_type("fcgi") -> fcgi;
get_ext_type(_)      -> regular.

yaws-2.0.2/src/Makefile.am0000664000175000017500000000736012605311412012245 00000000000000include @top_srcdir@/include.mk

STATIC_MODULES = yaws.erl			\
		 yaws_app.erl			\
		 yaws_ticker.erl		\
		 yaws_config.erl		\
		 yaws_server.erl		\
		 yaws_sup.erl			\
		 yaws_api.erl			\
		 yaws_log.erl			\
		 yaws_trace.erl			\
		 yaws_logger.erl		\
		 yaws_ls.erl			\
		 yaws_debug.erl			\
		 yaws_compile.erl		\
		 yaws_ctl.erl			\
		 yaws_cgi.erl			\
		 yaws_zlib.erl			\
		 mime_type_c.erl		\
		 yaws_session_server.erl	\
		 yaws_outmod.erl		\
		 yaws_revproxy.erl		\
		 yaws_html.erl			\
		 yaws_log_file_h.erl		\
		 yaws_rss.erl			\
		 yaws_appmod_dav.erl		\
		 yaws_runmod_lock.erl		\
		 yaws_pam.erl			\
		 json.erl			\
		 json2.erl			\
		 jsonrpc.erl			\
		 yaws_jsonrpc.erl		\
		 yaws_xmlrpc.erl		\
		 haxe.erl			\
		 yaws_rpc.erl			\
		 yaws_soap_srv.erl		\
		 yaws_soap_lib.erl		\
		 yaws_soap12_lib.erl		\
		 yaws_appmod_cgi.erl		\
		 yaws_appmod_fcgi.erl		\
		 yaws_sendfile.erl		\
		 yaws_sup_restarts.erl		\
		 yaws_stats.erl			\
		 yaws_vdir.erl			\
		 yaws_multipart.erl		\
		 yaws_shaper.erl		\
		 yaws_dime.erl			\
		 yaws_exhtml.erl		\
		 yaws_sse.erl			\
		 yaws_websockets.erl

EXTRA_DIST = $(STATIC_MODULES) yaws_websockets.erl yaws_debug.hrl	\
	     yaws_generated.template yaws.app.src yaws.app.src.script	\
	     yaws.appup.src

GENERATED_MODULES = yaws_generated.erl mime_types.erl
MODULES           = $(STATIC_MODULES) $(GENERATED_MODULES)


EBIN_DIR=@top_builddir@/ebin
EBIN_FILES=$(MODULES:%.erl=$(EBIN_DIR)/%.beam)

ERLC_FLAGS = $(ERLC_GENERIC_FLAGS)

include @top_srcdir@/erlang_deps.mk

all-local: $(EBIN_DIR)/yaws.app $(EBIN_DIR)/yaws.appup $(EBIN_FILES)

tags: $(EBIN_DIR)/yaws_generated.beam $(EBIN_DIR)/yaws_debug.beam
	$(AM_V_GEN)erl  -noshell -pa $(EBIN_DIR) -s yaws_debug mktags

xref: $(EBIN_DIR)/yaws_generated.beam $(EBIN_DIR)/yaws_debug.beam
	$(AM_V_GEN)erl -noshell -pa $(EBIN_DIR) -s yaws_debug xref $(EBIN_DIR)

clean-local:
	$(AM_V_at)rm -f $(EBIN_DIR)/yaws.app $(EBIN_DIR)/yaws.appup $(EBIN_FILES)
	$(AM_V_at)rm -f yaws_generated.erl mime_types.erl


yaws_generated.erl: @srcdir@/yaws_generated.template @top_srcdir@/vsn.mk \
		    $(EBIN_DIR)/yaws.beam
	$(AM_V_at)(cd @srcdir@ &&	\
	  YAWS_VSN='@YAWS_VSN@'		\
	  VARDIR='@localstatedir@'	\
	  ETCDIR='@sysconfdir@'		\
	    @abs_top_srcdir@/scripts/gen-yaws-generated) > yaws_generated.erl


mime_types.erl: @top_builddir@/priv/mime.types $(EBIN_DIR)/mime_type_c.beam \
		$(EBIN_DIR)/yaws.beam
	$(AM_V_GEN)$(ERL) -noshell -pa $(EBIN_DIR) -s mime_type_c generate

$(EBIN_DIR)/yaws.app: @srcdir@/yaws.app.src
	$(AM_V_GEN)$(AWK) -v src="$(MODULES)"				\
	"/{vsn, *{cmd,/ { 						\
		line = \$$0; 						\
		sub(/{vsn.*/, \"{vsn, \\\"@YAWS_VSN@\\\"},\", line);	\
		print line; 						\
		next; 							\
	}								\
	/{modules,/ {							\
		line = \$$0;						\
		indent = index(line, \"[\"); 				\
		line = substr(line, 1, indent);				\
		print line;						\
		split(src, mods);					\
		mods_count = 0; 					\
		for (mod in mods) { 					\
			mods_count++; 					\
		} 							\
		prefix = sprintf(\"%*s\", indent, \" \");		\
		for (i = 1; i <= mods_count; i++) { 			\
			mod = mods[i]; 					\
			sub(/\.erl/, \"\", mod); 			\
			if (i != mods_count) 				\
				print prefix mod \",\";			\
			else 						\
				print prefix mod;			\
		}							\
		print prefix \"]},\";					\
		next;							\
	} 								\
	/\@APPDEPS\@/ {							\
		line = \$$0;						\
		sub(/\@APPDEPS\@/, \"$(APPDEPS)\", line);		\
		print line; 						\
		next;							\
	}								\
	{ print; }" $< > $@

$(EBIN_DIR)/yaws.appup: @srcdir@/yaws.appup.src
	$(AM_V_GEN)sed -e "s/%VSN%/@YAWS_VSN@/g" < $< > $@

$(EBIN_DIR)/%.beam: %.erl
	$(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $<
	$(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $<


distclean-local:
	$(AM_V_at)rm -fr $(DEPDIR)

# Local Variables:
#    tab-width: 8
# End:
yaws-2.0.2/src/yaws_stats.erl0000664000175000017500000001215112605311412013110 00000000000000%%%-------------------------------------------------------------------
%%% File    : yaws_stats.erl
%%% Author  : Olivier Girondel 
%%% Description : Statistics module for Yaws
%%%
%%% Created : 11 Apr 2009 by Olivier Girondel 
%%%-------------------------------------------------------------------
-module(yaws_stats).

-behaviour(gen_server).

-include("../include/yaws.hrl").

%% API
-export([start_link/0, stop/1]).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

-export([hit/0, sent/1]).
-export([get/1]).

%% statistics
-record(stats, {
          hits = 0,
          sent = 0
         }).

%%====================================================================
%% API
%%====================================================================
%%--------------------------------------------------------------------
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
%% Description: Starts the server
%%--------------------------------------------------------------------
start_link() ->
    gen_server:start_link(?MODULE, [], []).


stop(Pid) ->
    gen_server:cast(Pid, {stop}).


hit() ->
    case get_stats() of
        undefined ->
            ok;
        Pid ->
            gen_server:cast(Pid, {hit})
    end.

sent({ok, Bytes}) ->
    sent(Bytes);
sent({error, _}) ->
    ignore;
sent(Bytes) ->
    case get_stats() of
        undefined ->
            ok;
        Pid ->
            gen_server:cast(Pid, {sent, Bytes})
    end.


get(Pid) ->
    case Pid of
        undefined ->
            undefined;
        Pid ->
            gen_server:call(Pid, {get})
    end.


%%====================================================================
%% gen_server callbacks
%%====================================================================

%%--------------------------------------------------------------------
%% Function: init(Args) -> {ok, State} |
%%                         {ok, State, Timeout} |
%%                         ignore               |
%%                         {stop, Reason}
%% Description: Initiates the server
%%--------------------------------------------------------------------
init([]) ->
    {ok, #stats{}}.

%%--------------------------------------------------------------------
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
%%                                      {reply, Reply, State, Timeout} |
%%                                      {noreply, State} |
%%                                      {noreply, State, Timeout} |
%%                                      {stop, Reason, Reply, State} |
%%                                      {stop, Reason, State}
%% Description: Handling call messages
%%--------------------------------------------------------------------
handle_call({get}, _From, State) ->
    Reply = {State#stats.hits, State#stats.sent},
    {reply, Reply, State};


handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
%%                                      {noreply, State, Timeout} |
%%                                      {stop, Reason, State}
%% Description: Handling cast messages
%%--------------------------------------------------------------------
handle_cast({hit}, Stats) ->
    NewHits = Stats#stats.hits+1,
    {noreply, Stats#stats{hits=NewHits}};


handle_cast({sent, Bytes}, Stats) ->
    NewSent = Stats#stats.sent+Bytes,
    {noreply, Stats#stats{sent=NewSent}};


handle_cast({stop}, Stats) ->
    {stop, normal, Stats};


handle_cast(_Msg, State) ->
    {noreply, State}.

%%--------------------------------------------------------------------
%% Function: handle_info(Info, State) -> {noreply, State} |
%%                                       {noreply, State, Timeout} |
%%                                       {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info(_Info, State) ->
    {noreply, State}.

%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> void()
%% Description: This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any necessary
%% cleaning up. When it returns, the gen_server terminates with Reason.
%% The return value is ignored.
%%--------------------------------------------------------------------
terminate(_Reason, _State) ->
    ok.

%%--------------------------------------------------------------------
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
%% Description: Convert process state when code is changed
%%--------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
get_stats() ->
    (erlang:get(sc))#sconf.stats.
yaws-2.0.2/www/0000775000175000017500000000000012605311413010321 500000000000000yaws-2.0.2/www/json_intro.yaws0000664000175000017500000002245112605311413013336 00000000000000



box(Str) ->
    {'div',[{class,"box"}],
     {pre,[], yaws_api:htmlize(Str)}}.

tbox(T) ->
    box(lists:flatten(io_lib:format("~p",[T]))).


ssi(File) ->
    {'div',[{class,"box"}],
     {pre,[],
      {ssi, File,[],[]}}}.

ss(A, File) ->
    {ok, B} = file:read_file(
                filename:join([A#arg.docroot, File])),
    box(binary_to_list(B)).



out(A) ->
    [{ssi, "TAB.inc", "%%",[{"json_intro", "choosen"}]},
     {ehtml,
      {'div', [{id, "entry"}],

      [{h1, [], "AJAX through JSON RPC"},

        {p, [],
         {i, [],
          ["Note: this documentation used to refer to the module "
           "'yaws_jsonrpc', but that module was deprecated in favor of "
           "'yaws_rpc', which handles JSON RPC, haXe and SOAP remoting. "
           "For more specific information about SOAP, refer to ",
           {a, [{href, "/soap_intro.yaws"}], "the SOAP page."}]}},
       {p, [],
        ["The Yaws JSON-RPC binding is a way to have JavaScript code in the "
         "browser evaluate a remote procedure call (RPC) in the Yaws server. "
         "JSON itself as described at ",
         {a, [{href, "http://www.json.org/"}], "http://www.json.org/ "},
         "is basically a simple marshaling format which can be used "
         "from a variety of different programming languages, and "
         "naturally it's completely straightforward to implement "
         "in JavaScript itself. JSON-RPC version 2.0, the version Yaws "
         "supports, is described here:"]},
       {p, [],
        [{a, [{href,
         "http://groups.google.com/group/json-rpc/web/json-rpc-2-0"}],
         "http://groups.google.com/group/json-rpc/web/json-rpc-2-0"}]},
       {p, [],
        "The Yaws JSON-RPC implementation consist of JavaScript clients and a "
        "server side library that must be explicitly invoked by Erlang "
        "code in a .yaws page, appmod, etc."},

       {p,[],
        "It is not particularly easy to show and explain an AJAX setup "
        "through JSON-RPC, but here is an attempt:"
        },
       {p,[],
        "First we have an HTML page which:"},
       {ol, [],
        [
         {li,[],{p,[],
                 ["Includes the client side of the JSON library. "
                  "The library is included in the Yaws distribution "
                  "and it is found under ",
                  {a,
                   [{href,
                     "https://github.com/klacke/yaws/blob/master/www/jsolait/jsolait.js"}],
                   "\"www/jsolait/jsolait.js\""}, "."]}},
         {li,[],{p,[],"Second, the HTML code defines the name of a method, "
                 "i.e. the name of a server-side function that shall be "
                 "called by the client side JavaScript code."}},
         {li,[],{p,[],"Finally the HTML code defines a FORM that's "
                 "used to invoke the RPC. This is just a really simple "
                 "example, really any JavaScript code can invoke any RPC in "
                 "more interesting scenarios than submitting a form."}}]},

       {p, [], "The HTML code appears as shown below:"},
       ss(A,"json_sample.html"),
       {p, [], ["This HTML code resides in file ",
                {a,[{href, "json_sample.html"}], "json_sample.html"},
                " and it is the HTML code that is the AJAX GUI."]},
       {p, [], "Following that we need to take a look at json_sample.yaws "
        " (shown below), which is the \"serviceURL\" according to "
        "the JavaScript code. This code defines the function to be "
        "called. Remember that the JavaScript code defined one method, "
        "called \"test1\"; this information will be passed to the "
        "serviceURL. The code looks like:"},
       ss(A, "json_sample.yaws"),

       {p,[], "The two important lines on the server side are"},
       {ol,[],
        [
         {li,[],
          {pre,[],"yaws_rpc:handler_session(A2, {sample_mod, counter})."}},
         {li,[],
          {pre,[],"counter([{ip, IP}] = _State, {call, test1, Value} = _Request, Session)"}}]},

       {p,[],
        ["The first line tells Yaws to forward all JSON-RPC methods to the "
         " \"counter\" function in the \"sample_mod\" module. "
         "The second line is the head of the counter function that will be "
         "called when the client invokes a method called 'test1'. We would "
         "duplicate this line with a different name than 'test1' for each RPC "
         "function we wish to implement. Note that the first atom in the "
         "request tuple will either be 'call' or 'notification' to indicate "
         "the type of request. As per the ",
         {a,[{href,"http://groups.google.com/group/json-rpc/web/json-rpc-2-0"}],
          "JSON-RPC 2.0 specification"},
         ", a 'call' is a regular request-reply while a 'notification' is a "
         "one-way message that does not have a corresponding reply."]},

       {p,[],"On the client side we have"},

       box("
var methods = [ \"test1\" ];
var jsonrpc = imprt(\"jsonrpc\");
var service = new jsonrpc.ServiceProxy(serviceURL, methods);
"),

      {p,[],"This registers the Yaws page with the JSON-RPC handler and "
            "gives it a list of methods that the Yaws page can satisfy. "
            "In this case, the only method called 'test1'."},

      {p, [],
"When we wish to return structured data, we simply let "
"the user-defined RPC function return JSON structures such as "},

box("{struct, [{field1, \"foo\"}, {field2, \"bar\"}]} "),
{p, [], " for a structure and "},
box("{array, [\"foo\", \"bar\"]}"),
{p, [],"for an array. We can nest arrays and structs in each other."},

       {p, [],
        "Finally, we must stress that this example is extremely simple. "
        "In order to build a proper AJAX application in Yaws, a lot of "
        "client side  work is required, all Yaws provides is the basic "
        "mechanism whereby the client side JavaScript code can RPC the "
        "web server for data which can be subsequently used to populate "
        "the DOM. Also required to build a good AJAX application is "
        "good knowledge of how the DOM in the browser works"},

       {p, [],
        ["The yaws_rpc:handler will also call: M:F(cookie_expire) "
         "which is expected to return a proper Cookie expire string. This "
         "makes it possible to setup the Cookie lifetime. If this callback "
         "function is non-existent, the default behaviour is to not set a "
         "cookie expiration time, i.e., it will live for this session only."]},

       {h3, [], "One more example "},

       {p, [],
        ["Here is yet another example, stolen from ",
         {a,
          [{href,"http://www.redhoterlang.com/entry/ac061493b201e3d1b4490cdc3f911068"}],
          "Tobbe's blog."}
         ]},
        {h4, [], "Setup the DOM"},
        {p, [], "In the file ''ex1.html'' we create the DOM with a little HTML and add some JavaScript that will talk with the Erlang server side."},
        box("













This is one
This is two
This is three
"), {h4, [], "The erlang server side"}, {p, [], "This is the code that needs to be installed and " "execute on the server side. It nicely illustrates how " "to return JSON structs to the client. "}, box(" -module(ex1). -export([out/1]). out(A) -> L = yaws_api:parse_query(A), dispatch(lkup(\"op\", L, false), A, L). dispatch(\"ex1\", A, L) -> ex1(A, L). ex1(_A, L) -> J = json2:encode(array(what(lkup(\"what\", L, false)))), return_json(J). what(\"one\") -> one(); what(\"two\") -> one() ++ two(); what(\"three\") -> one() ++ two() ++ three(). array(L) -> {array, L}. one() -> obj(\"one\"). two() -> obj(\"two\"). three() -> obj(\"three\"). obj(M) -> obj(M, \"r\"). %%% %%% How ::= \"r\" | \"a\" , r=replace, a=append %%% obj(M, How) -> C = now2str(), [{struct, [{\"who\", M}, {\"how\", How}, {\"what\", C ++\" \"++M++\" content\"}]}]. return_json(Json) -> {content, \"application/json; charset=iso-8859-1\", Json}. now2str() -> {A,B,C} = erlang:now(), i2l(A)++\"-\"++i2l(B)++\"-\"++i2l(C). i2l(I) when is_integer(I) -> integer_to_list(I); i2l(L) when is_list(L) -> L. lkup(Key, List, Def) -> case lists:keysearch(Key, 1, List) of {value,{_,Value}} -> Value; _ -> Def end. ") , {h2, [], "The json library"}, {p, [], ["The Yaws JSON library contains 3 simple functions, " " one for encoding and two for decoding. See source code ", {a, [{href, "https://github.com/klacke/yaws/blob/master/src/json2.erl"}], "json2.erl"}, " for detailed instructions on usage."]} ]}}, {ssi, "END2",[],[]} ].
yaws-2.0.2/www/logger_mod.yaws0000664000175000017500000001201112605311413013257 00000000000000 out(A) -> {ssi, "TAB.inc", "%%",[{"logger_mod", "choosen"}]}.

Write your own logger

To illustrate how to write a module that handles auth and access logging in Yaws, we will get a concrete example: How to log the original client IP behind a HTTP reverse proxy.

When Yaws is running behind a HTTP reverse proxy, the source IP of a connection is always the proxy's IP address. It is also this IP address that you will find in your log files. In this situation, it may be desirable to log the real client IP address by extracting it from the "X-Forwarded-For" header.

It can easily be done by writting a simple module to handle access and auth logging on top of yaws_log. yaws_log is the default logger of Yaws and it can be overridden by using the directive "logger_mod" in yaws.conf:

port = 80 listen = 0.0.0.0 logger_mod = simple_logger ...

In this example, "simple_logger" will be used in place of yaws_log. This module must implement the behaviour yaws_logger by exporting the following functions:

Module:open_log(ServerName, Type, LogDir) -> {true, State} | false. ServerName :: string() Type :: access | auth LogDir :: string() State :: term() Module:close_log(ServerName, Type, State) -> ok. ServerName :: string() Type :: access | auth State :: term() Module:wrap_log(ServerName, Type, State, LogWrapSize) -> NewState. ServerName :: string() Type :: access | auth State, NewState :: term() Module:write_log(ServerName, Type, State, Infos) -> ok. ServerName :: string() Type :: access | auth State :: term() Infos :: {Ip,Req,InHdrs,OutHdrs,Time} | %% when type =:= access {Ip,Path,Item} %% when type =:= auth Ip :: inet:ip_address() | inet:hostname() | unknown Req :: #http_request{} %% defined in yaws_api.hrl InHdrs :: #headers{} %% defined in yaws_api.hrl OutHdrs :: #outh{} %% defined in yaws.hrl Time :: non_neg_integer() %% The time taken to serve the request, in microseconds Path :: string() %% the URI path of the request Item :: {ok, User} | 403 | {401, Realm} %% the result of an auth request

Back to our example. The only thing we want to do is read the "X-Forwarded-For" header to extract the real client IP address. The logging will be delegated to yaws_log.

If the "X-Forwarded-For" header is defined, then the originating IP address of a client is the left-most IP address. But, because this header can be falsified, we will define a list of trustworthy proxies. For simplicity, we will use a macro. Here is our logger:

-module(yaws_revproxy_logger). -behaviour(yaws_logger). -include_lib("yaws/include/yaws.hrl"). -include_lib("yaws/include/yaws_api.hrl"). -export([open_log/3, close_log/3, wrap_log/4, write_log/4]). -define(REVPROXY_WHITELIST, [{192,168,0,1}, {192,168,0,2}]). %% =================================================================== open_log(ServerName, Type, Dir) -> yaws_log:open_log(ServerName, Type, Dir). close_log(ServerName, Type, State) -> yaws_log:close_log(ServerName, Type, State). wrap_log(ServerName, Type, Data, LogWrapSize) -> yaws_log:wrap_log(ServerName, Type, Data, LogWrapSize). write_log(ServerName, auth, State, {Ip, Path, Item}) -> yaws_log:write_log(ServerName, auth, State, {Ip, Path, Item}); write_log(ServerName, access, State, {Ip, Req, InH, OutH, Time}) -> RealIp = real_client_ip(Ip, ?REVPROXY_WHITELIST, InH), yaws_log:write_log(ServerName, access, State, {RealIp, Req, InH, OutH, Time}). real_client_ip(Ip, ProxyWhitelist, Hdrs) -> case lists:member(Ip, ProxyWhitelist) of true -> FwdFor = Hdrs#headers.x_forwarded_for, case yaws:split_sep(FwdFor, $,) of [FirstIp|_Proxies] -> %% We might check if the last proxy is the remote %% address of the request, i.e hd(_Proxies) =:= Ip. case inet_parse:address(FirstIp) of {error, _} -> unknown; {ok, ClientIp} -> ClientIp end; [] -> Ip end; false -> Ip end.

Now, we just need to compile this module and update yaws.conf accordingly.

Note: In previous version of Yaws, we could use "x_forwarded_for_log_proxy_whitelist" to do the same thing. This parameter is now deprecated.

out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/json_sample.html0000664000175000017500000000261712605311413013447 00000000000000 Testing html-json library

First Argument:

Second Argument:

yaws-2.0.2/www/testdir/0000775000175000017500000000000012605311413011777 500000000000000yaws-2.0.2/www/testdir/index.html0000664000175000017500000000101312605311413013707 00000000000000 Hyber test of rel urls

XX swedish chars a.jpg swedish chars swedish chars swedish chars yaws-2.0.2/www/redirect3.yaws0000664000175000017500000000013012605311413013024 00000000000000 %% redirect 3 yaws out(_Arg) -> {redirect_local, "/redirect2.yaws"}. yaws-2.0.2/www/code.yaws0000664000175000017500000000147412605311413012066 00000000000000 out(A) -> {Code, F} = case queryvar(A, "file") of {ok, Fname} -> File = A#arg.docroot ++ yaws_api:sanitize_file_name(Fname), case file:read_file(File) of {ok, B} -> C = {'div', [], {pre, [], B}}, {C, Fname}; _ -> {[], "Can't read " ++ Fname } end; undefined -> {[], "Bad request"} end, {ehtml, {html, [], {'div', [], [{h2, [], F}, Code]}}}. yaws-2.0.2/www/examples.yaws0000664000175000017500000000140612605311413012765 00000000000000 out(A) -> yaws_api:ssi(A#arg.docroot, ["/HEAD", "/EXHEAD"]).

Yaws Examples

Here we try to show the power of yaws by means of a series of examples. Many of the pages inside this documentation, use embedded erlang code merely as a means to include files into the HTML documentation. Yaws can be used to do much more which is shown by the examples.

It can be used to generate any dynamic content, and also, combining Yaws with the Erlang DBMS Mnesia, we can easily connect persistent data to a Cookie.

In all of the examples we will utilize the yaws api functions defined in the module yaws_api. The documentation for the API module is here. out(A) -> yaws_api:ssi(A#arg.docroot, ["/END"]). yaws-2.0.2/www/yman.yaws0000664000175000017500000000311112605311413012106 00000000000000 prebox(Str) -> {'div',[{class,"man"}], {pre,[], yaws_api:htmlize(Str)}}. out(A) -> H = {ssi, "TAB.inc", [],[]}, L = case queryvar(A,"page") of {ok, Page} -> %% only allow regular chars in Page case lists:all(fun(C) -> if $a =< C, C =< $z -> true; $A =< C, C =< $Z -> true; C == $_ -> true; C == $. -> true; true -> false end end, Page) of true -> %os:cmd("man " ++ Page ++ " | col -b -p -x"); unesc(os:cmd("man " ++ Page)); false -> "illegal character detected in query arg" end; undefined -> "no man page found in query arg " end, Man = {ehtml, {'div', [{id, "entry"}], prebox(unicode:characters_to_binary(L))}}, Trail = {ssi, "END2",[],[]}, [H, Man, Trail]. unesc([27 | T]) -> unesc(uptom(T)); unesc([H|T]) -> [H|unesc(T)]; unesc([]) -> []. uptom([$m|T]) -> T; uptom([H|T]) -> uptom(T); uptom([]) -> []. yaws-2.0.2/www/doc.yaws0000664000175000017500000000164712605311413011723 00000000000000 out(A) -> {ssi, "TAB.inc","%%",[{"doc", "choosen"}]}.

Documentation

User manual

The version of the usermanual is currently getting a bit old. There are several features of yaws which are yet not properly described in the user manual, they are all described in the Example collection or man pages though.

Man pages

out(_) -> {ssi, "END2", [],[]}. yaws-2.0.2/www/bindings.yaws0000664000175000017500000000434012605311413012744 00000000000000 out(A) -> {ssi, "TAB.inc", "%%",[{"bindings", "choosen"}]}.

Bindings

Bindings are the opposite of Server Side Includes (SSI). SSI is used when entire pages are written largely in EHTML and snippets of HTML, or more typically javascript code is inserted into the EHTML code.

Bindings are used the other way around. Essentially entire pages are written in regular HTML but parts of the HTML needs to be dynamically generated.

The yaws callback out/1 can return

      {bindings, [{Key1, Value2}, {Key2, Value2} .....]}.
    

All bindings can then be used in the rest of yaws code (in HTML source and within erl tags). In HTML source %%Key%% is expanded to Value and within erl tags yaws_api:get_binding(Key) can be used to extract Value.

With the binding feature it is easier to write transparent yaws code making it easier to to work together with Web people knowing little or nothing about Erlang.

An example:

out(A) -> {bindings, [{"A", "foo"}, {"B", "baz"}]}.

%%A%%

%%A%% != %%B%%

An enormous amount of plain html source here.

out(A) -> Value = yaws_api:binding("A"), {ehtml, {ul, [], [{li, [], Value}, {li, [], "gazonk"}]}}. %%A%% = %%A%% (hit me)

Which expands to:

foo

foo != baz

An enormous amount of plain html source here.

  • foo
  • gazonk
foo = foo (hit me)

And is rendered as:

foo

foo != baz

An enormous amount of plain html source here.

  • foo
  • gazonk
foo = foo (hit me)
out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/setcookie.yaws0000664000175000017500000000216612605311413013140 00000000000000 session(A, Visits) -> receive {From, tick} -> N = calendar:local_time(), From ! {self(), [N|Visits]}, session(A, [N|Visits]) after 60000 -> %% keep state for 60 secs only exit(normal) end. out(A) -> H = A#arg.headers, C = H#headers.cookie, case yaws_api:find_cookie_val("foobar", C) of [] -> Now = calendar:local_time(), P = spawn(fun() -> session(A, [Now]) end), yaws_api:set_cookie("foobar", pid_to_list(P), [{path,"/"}]); PidStr -> Pid = list_to_pid(PidStr), case process_info(Pid, messages) of undefined -> Now = calendar:local_time(), P = spawn(fun() -> session(A, [Now]) end), yaws_api:set_cookie("foobar", pid_to_list(P), [{path,"/"}]); _ -> ok end end. yaws-2.0.2/www/spacer.gif0000664000175000017500000000005312605311413012203 00000000000000GIF89a€!ù, ;yaws-2.0.2/www/yaws-1.55_to_1.56.patch0000664000175000017500000000157312605311413014014 00000000000000 Index: yaws_api.erl =================================================================== RCS file: /cvsroot/erlyaws/yaws/src/yaws_api.erl,v retrieving revision 1.126 retrieving revision 1.128 diff -u -b -r1.126 -r1.128 --- yaws_api.erl 16 May 2005 21:12:03 -0000 1.126 +++ yaws_api.erl 16 Jun 2005 11:36:57 -0000 1.128 @@ -741,11 +741,14 @@ url_decode_q_split([$%, Hi, Lo | Tail], Ack) -> Hex = yaws:hex_to_integer([Hi, Lo]), + if Hex == 0 -> exit(badurl); + true -> ok + end, url_decode_q_split(Tail, [Hex|Ack]); url_decode_q_split([$?|T], Ack) -> %% Don't decode the query string here, that is parsed separately. {path_norm_reverse(Ack), T}; -url_decode_q_split([H|T], Ack) -> +url_decode_q_split([H|T], Ack) when H /= 0 -> url_decode_q_split(T, [H|Ack]); url_decode_q_split([], Ack) -> {path_norm_reverse(Ack), []}. yaws-2.0.2/www/compile_layout.dia0000664000175000017500000000245712605311413013755 00000000000000‹í[]o£8}ϯ@TíJÔ`‰3tÔJ»š‡­öa;Ï•\ÂÔœ¶y™ß¾6Ð&ᣡ€Ò‚”J¸7÷`s|îäÛ÷çÓiœQ8Ó!°t†‹È B¦ÿ¼ýûëß/Gß¼€|?&+M|#LäÙL_r¾þjšOOO€m£°`jþ&ŒS™úåHÓöx„9–Îã`¾áT ÉŠÎô9Y<øq´ ==³Êí‹bí‘°™~vŸº™»1ü¼á{M|:)y¨wm‰c:mãzMã¢ÛÕ:Ja·ë’IùwÏ&·J„Qè_ž]9gÙ%å;_UZ ÂW$öƒ°Œ#Ö†e F½¬Ãû!æê!˜zˆX=DÜ­£˜Ç$àe˜y1J ‰ÇÚ'Y&(óÖT`{ï÷çÑ‘ë¿',i2løu÷¼w'úqཽ,j¼<_Þ=+Z®ÌûV‘÷Ç æŒV]}òÞÜoûq_¼;©ï¾Þ‘ ™·Z¹÷0u©û~¹÷7G“#4;´©ñ´ÌÍÌc«^´kº0ÙP!ø¦Œliœ»¿Þ…]-¿Á¹âì­B4ÿE<ŸÞœ„‰=í\»Žžõ]!rˆÀ›éÿZ‡ËSœp&”¯´>ëè•D˜¨8á²\Ô9ŸÏ‹¾cqõ$ô}ñ]‚©{ÆÀr ˜¸íà(£«»E‡åßÏ|R€T5ÊszDÀÞ—4ð—¼Þ½ &í¼'Ëèé®"­;ãª÷£¹£bknÂîÜÄ’0Sµô8e'4àØjÉÙeB ù‰òs l÷ãõBPAÇULQ‰‘ (²£œ£æÔTE]¥2:=E–ÞÒg^AS»+M]à Þ€±B’æ–Ü ˆÁN¤Ðá¶jÁåJÉa 6uw4-âì õþÆ/h̾øü"3Š6ü«?µóÝHv€ìØ‚–¥]o9M´è^û+fbE´EäQ-l#;<ûÖ|Iµ=4MÜøôÜ|•ðƒ¸û£ÑþhM7┿®~ŒB^µr\»'«€mÅz‘0ѵ„oen*˜}õe” ²ŸB¿ÿ Jû¶bïZw9Ü ÍöCœÃªçV—eu",ðí¾y4ܬò…kˆRYÓ(0§«€ÉÜLe(ýcàäâ厅xA(ÄìDÔk‰Rõ¸Ùj?noþÉHà UZÒ8“3³yñsÅ|*)Öаy®a/ÿõ3ˆOßâSàò <*•Çíª<¢ t  • ¾ÀÊ#”#Žñ ˆÏ }«Cß…P©ãîÅ•cˆ¤*-®Y‘»2?A@²¸B¶POP]ÝD"ƒJ¬Ó+±Š»b1…ÌIWKÛß*ŸeÍËôA V·.øÑ.f—ù4é`:b"J˜Øý@LÜ™ž€ §mã»A%„ ° ²¶ldÓè`¾v!‡8Öw+oˆc ãØ´8æXĵ± Xıô9™ê0Öe:ÍBVûÄø2hõÉl¢ÖoÁ4e)ÄY0sd0ƒ¶8?h††h¦0š•È7Ä3¥‚Ñù%(„ÁØ@Œ• .–=h,©('Cú3êDçPùª$ê!ñµÒ÷¶\µ™o !S_Ù€Vœúv›PÃ6Îð6oÓPf÷ûŠjY­_"mšü 8“<ûEò}:ÁC/ç“g¿eú a­™fdçé¯Y.G?w¹ýUáöâ:yaws-2.0.2/www/END20000664000175000017500000000043612605311413010657 00000000000000

Valid XHTML 1.0!

yaws-2.0.2/www/json_sample.yaws0000664000175000017500000000241212605311413013457 00000000000000 -compile(export_all). out(A) -> Peer = case yaws_api:get_sslsocket(A#arg.clisock) of {ok, SslSocket} -> ssl:peername(SslSocket); _ -> inet:peername(A#arg.clisock) end, {ok,{IP,_}} = Peer, A2=A#arg{state = [{ip, IP}]}, yaws_rpc:handler_session(A2, {?MODULE, counter}). counter([{ip, IP}] = _State, {call, errortest, Value} = _Request, Session) -> io:format("Request = ~p~n", [_Request]), { false, { error, "Expected failure" } }; counter([{ip, IP}] = _State, {call, test1, Value} = _Request, Session) -> io:format("Request = ~p~n", [_Request]), IPStr = io_lib:format("Client ip is ~p~n" , [ IP ]), OldSession = io_lib:format("Request is: ~p~nOld session value " "is ~p~n", [ _Request, Session ]), case Session of undefined -> % create new session NewSession = 0; 10 -> % reset session after reaching 10 NewSession = undefined; N -> NewSession = N + 1 end, NewVal = io_lib:format("New session value is ~p ~n", [ NewSession ]), Str = lists:flatten([IPStr,OldSession,NewVal]), {true, 0, NewSession, {response, Str }}. yaws-2.0.2/www/stil.css0000664000175000017500000000334212605311413011730 00000000000000 html {margin: 0; padding: 0;} body {font: 12px Verdana, Arial, Helvetica, sans-serif; margin: 0; padding: 0; background: rgb(95%,95%,95%); color: black;} h1 {font-size: 200%; text-transform: lowercase; letter-spacing: 3px; margin: 0.66em 0 0.33em 3%; padding: 0;} h3 {font-size: 133%; margin: 0; padding: 0; border-bottom: 1px solid black;} h4 {font-size: 100%; margin: 0; padding: 0.33em 0 0; border-bottom: 1px solid rgb(50%,50%,35%); color: rgb(50%,50%,35%);} h5 {font-size: 100%; margin: 0; padding: 0.33em 0 0; color: rgb(50%,50%,35%);} p {line-height: 1.66; margin: 0.3em 0.2em 1em 0em;} code {background: rgb(211, 211, 211); font: 11px monospace; padding: 0 1px; } div.logo {margin: 3em;} div#entry {margin: 0 33% 1em 7%; padding: 0;} div#sidebar {position: absolute; top: 4em; right: 0; width: 20%; font-size: 11px;} div#sidebar a {display: block; padding: 8px 0 2px 10px; margin: 0; border-left: 1px solid rgb(50%,50%,35%);} div#sidebar a:hover {background: rgb(221,221,221);} div.links { background: green; } div.box { border: solid; border-width: thin; width: 96%; background: rgb(211, 211, 211) } div.news { border: solid; border-width: thin; width: 96%; border-bottom: 3px solid black; margin: 18px 5px 2px 10px; background: rgb(211, 211, 211) } div.box pre {margin: 0.66em 0 0.33em 1%; padding: 0;} div.man { border: solid; border-width: thin; width: 100%; font-size: 90%; margin : 4; background: rgb(211,211,211) } div.choosen {border: solid; border-width: thin; background: rgb(231, 231, 231) } div.none { } I { font-size : 12px; font-family: Times, Verdana, Arial, Helvetica, sans-serif;} yaws-2.0.2/www/server_sent_events.yaws0000664000175000017500000001340712605311413015076 00000000000000 out(A) -> {ssi, "TAB.inc", "%%",[{"sse", "choosen"}]}.

Server-sent events

HTTP is a client-server protocol — the client makes a request and the server replies with a response. For some applications, though, the request-reply model is limiting or unsuitable. These applications tend to want server-to-client notification capabilities. While such notifications can be simulated using polling, and web-based polling can be much more efficient than one would think due to intermediary caching, it's still less efficient and less timely than a notification model.

Yaws users have a few options for notification-oriented applications:

  • Yaws supports an older technique called "long polling" or "Comet" where the client sends a request that the server sits on and doesn't answer until it actually has an event for the client. The problem with long polling is that it requires the client and server applications to be bound tightly to each other via the specialized ad hoc long-polling protocol they share.

  • The WebSockets protocol (RFC 6455) allows web client and server to upgrade their TCP connection from using HTTP to using some other protocol they agree on. The protocol they choose can be bidirectional and can transmit whatever data transfer formats they wish to use. WebSockets afford applications a great deal of freedom and flexibility, but they also require client and server to agree on specialized protocols, framing, and data formats to be able to communicate successfully.

  • Server-Sent Events (SSE) is a W3C working draft that unlike long polling is on a path to standardization and unlike WebSockets is pretty simple. Despite being a working draft, it's already fairly widely used. With SSE, a client sends a standard HTTP request asking for an event stream, and the server responds initially with a standard HTTP response and holds the connection open. When appropriate, the server sends standard text-based event data back to the client as part of the initial response, and continues to do so until either end closes the connection. Clients can disconnect and later reconnect, indicate the last event they received, and pick up new events from that point.

Currently, Chrome, Firefox, Opera, and Safari support SSE. Older browsers do not support SSE directly, but they can be made to do so with suitable JavaScript packages.

Writing a Yaws SSE application

Yaws supports SSE through its streaming capabilities. SSE applications typically consist of an entry point page and an appmod. The entry page returns HTML and JavaScript that acts as the SSE client, with the JavaScript invoking the appmod's out/1 function that creates a streaming process responsible for sending events back to the client. The appmod uses the yaws_sse module to properly format and send its event data.

Yaws supplies an example that uses SSE to return the server's time of day clock to the client. Each second, the server sends a new event to the client updating its time of day, which the client dynamically displays in a web page.

Note: if you're running this on your own Yaws installation, make sure your server configuration includes the following appmod entry:

appmods = <"/sse", server_sent_events>

and also make sure server_sent_events.beam is on the Yaws load path, which it should be if you followed regular installation procedures.

First, the entry HTML page is here: server_sent_events.html. It presents a page title and a placeholder for the server date string. It also supplies a bit of JavaScript that receives events from Yaws, using the browser's EventSource JavaScript class to receive them. It then pulls the data out of the event and displays it dynamically in the HTML.

Next, the server appmod code is here: server_sent_events.erl. Its out/1 function create a gen_server event generation process, returning the pid in a streamcontent_from_pid directive to Yaws along with suitable headers. Note that it obtains the desired out/1 return value via the yaws_sse:headers/1 function. Its gen_server is fairly simple in that it creates a timer that, once per second, generates a time of day string and sends it as an event to the client formatted via the yaws_sse:data/1 function.

The yaws_sse module supplies all the SSE primitives required for formatting event data, event identifiers, and event retry settings. See the Server-Sent Events working draft for more details on using these features.

The yaws_sse module also supplies functions for formatting and sending event data on a socket. If you're using the yaws_sse module outside of a Yaws streaming application, you should use the arity 3 version of yaws_sse:send_events and pass fun yaws:gen_tcp_send/2 as the third argument.

Note: be aware that because the W3C Server-Sent Events spec is still a working draft, any future changes in it might cause API-incompatible changes in how Yaws supports it.

out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/readcookie.yaws0000664000175000017500000000305212605311413013253 00000000000000

Read cookie

out(A) -> H=A#arg.headers, C = H#headers.cookie, L=case yaws_api:find_cookie_val("foobar", C) of [] -> f("

No cookie set from the browser, need to " "visit setcookie.yaws " "to set the cookie first ~n", []); PidStr -> Pid = list_to_pid(PidStr), Pid ! {self(), tick}, receive {Pid, VisitList} -> f("

Yes, I read your cookie " "You have vistited this page ~w times " "they were ~n

    ~n~s
~n " "Reloading this page will show the session state ", [length(VisitList), lists:map(fun(D) -> f("
  • ~p~n", [D]) end, VisitList) ]) after 500 -> f("

    You had a cookie, but the pid handling your sess " "timedout ...",[]) end end, {html, L}.

    The code to read the cookie, is simple, we get the cookie passed to the yaws code in the #arg structure which is the argument supplied to the out/1 function.

    We use the yaws_api:find_cookie_val/2 function to parse the raw cookie string passed to us from the browser. The code is: out(A) -> yaws_api:pre_ssi_files(A#arg.docroot, ["readcookie.yaws"]). yaws-2.0.2/www/rebar_release.yaws0000664000175000017500000001261112605311413013742 00000000000000 box(Str) -> {'div',[{class,"box"}], {pre,[], yaws_api:htmlize(Str)}}. out(A) -> [{ssi, "TAB.inc", "%%",[{"rebar_release", "choosen"}]}].

    Creating a Release with Rebar

    One way to create an Erlang release for a project that depends on Yaws, or a set of applications that includes Yaws, is to use the rebar build tool. This page details the steps required to set up the proper directory structure for such a project, create and generate the necessary release configuration files, and how to package a release for later installation and deployment.

    Rebar Templates

    The easiest way to build a release that uses Yaws is to use the rebar template files found under the rebar-templates directory found at the top-level of the Yaws repository. To do this, first copy all the files in the rebar-templates directory into your $HOME/.rebar/templates directory, creating it if necessary:

    $ mkdir -p ~/.rebar/templates
    $ cp rebar-templates/* ~/.rebar/templates
          

    Next, run rebar in your foo project directory to create a release project skeleton, specifying the yawsnode template so rebar knows what to create. Note also that we specify foo as the nodeid and myapp as the appid:

    $ cd /path/to/foo
    $ rebar create template=yawsnode nodeid=foo appid=myapp
          

    This creates two subdirectories and a rebar.config file, described below:

    apps
    holds directories for the applications that comprise the foo project
    rebar.config
    build configuration for the foo project
    rel
    provides support files for creating project releases

    The apps Directory

    Let's assume we have a single application named myapp that depends on Yaws, and myapp and Yaws together comprise the foo project. The apps directory therefore contains a myapp subdirectory, which is a normal Erlang project directory that should contain its own rebar.config file, a src directory containing Erlang source code, etc. Since myapp depends on Yaws, its rebar.config file should specify Yaws as a dependency. Note that the yawsnode rebar template does not create any of this for you; you're expected to create your own application files yourself.

    Building the Project

    To build the foo project, use rebar:

    $ rebar get-deps compile
          

    This first fetches all dependencies for all the applications under the apps directory, and the compiles them along with all the apps.

    Creating a Release

    Once everything is compiled, you can change to the rel directory and generate a release. Prior to that, though, you might want to edit the rel/files/yaws.conf file to ensure Yaws will be configured properly for your project when you run the generated release. That file is copied into the generated release. Once you've done that, run "rebar generate" in the rel directory:

    $ cd rel
    $ rebar generate
          

    Because we specified the nodeid as foo when we created the project, the generation step creates a foo directory under rel that holds the generated release. It contains an Erlang runtime along with all the standard and application-specific modules and support files needed to run your project, all in a relocatable directory structure. To package it for deployment, just tar it up:

    $ cd foo
    $ tar zcf ../foo.tar.gz *
          

    This packs up the whole release into the file rel/foo.tar.gz.

    Deploying the Project

    To deploy your project release, copy the tar file onto the target host, unpack it into an installation directory of your choice, and then run the install.sh script to ensure any absolute paths in the release reflect the chosen installation directory. You can then run the node using the bin/foo script:

    $ < login to target host, copy foo.tar.gz over >
    $ cd /install/path
    $ tar zxf foo.tar.gz
    $ ./install.sh
    $ ./bin/foo console
          

    The final command above starts the node with an interactive shell. Once it's running, Yaws and all the other applications that comprise the project will be executing. You can alternatively start the node as a daemon by running "./bin/foo start" and later stop it with "./bin/foo stop". Run "./bin/foo" with no arguments to see all its other command-line arguments.

    yaws-2.0.2/www/redirect4.yaws0000664000175000017500000000014212605311413013030 00000000000000 %% redirect4.yaws out(_Arg) -> {redirect_local, {any_path, "redirect2.yaws"}}. yaws-2.0.2/www/haxe_sample.html0000664000175000017500000000132112605311413013412 00000000000000// To try this sample out using haXe and neko, // save this file as Application.hx and run the following to compile it: // haxe Application -neko Application.n -main Application.hx // and the following to execute it: // neko Application.n class Application { public static function main():Void { var URL = "http://localhost:8000/haxe_sample.yaws"; var cnx = haxe.remoting.HttpAsyncConnection.urlConnect(URL); cnx.setErrorHandler( function(err) { trace("Exception : " + Std.string(err)); } ); var a = {a:"foo", b:"bar", c:[1,2,3]}; var b = "hello, Erlang!"; cnx.echo.call([a, b], display); cnx.failure.call([a, b], display); } static function display(v) { trace(v); } } yaws-2.0.2/www/ybed_sup.erl0000664000175000017500000000050412605311413012556 00000000000000-module(ybed_sup). -behaviour(supervisor). %% API -export([start_link/0]). %% Supervisor callbacks -export([init/1]). start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> YBed = {ybed, {ybed,start,[]}, permanent,2000,worker,[ybed]}, {ok,{{one_for_all,0,1}, [YBed]}}. yaws-2.0.2/www/privbind.yaws0000664000175000017500000001062012605311413012762 00000000000000 out(A) -> {ssi, "TAB.inc", "%%",[{"privbind", "choosen"}]}.

    Binding to privileged ports

    A common misfeature found on UN*X operating systems is the restriction that only root can bind to ports below 1024. Many a dollar has been wasted on workarounds and -often- the results are security holes.

    Both FreeBSD and Solaris have elegant configuration options to turn this feature off. On FreeBSD:

    $ sysctl net.inet.ip.portrange.reservedhigh=0
    the above is best added to your /etc/sysctl.conf

    Similarly on Solaris we can just configure away this misfeature. Assuming we want to run Yaws/SSL under a non-root user "erlang" on ports 80/443.

    On Solaris we can do that easily by granting the specific right to bind privileged ports <1024 (and only that) to "erlang" using:

    $ /usr/sbin/usermod -K defaultpriv=basic,net_privaddr erlang

    And check the we get what we want through:

    $ grep erlang /etc/user_attr erlang::::type=normal;defaultpriv=basic,net_privaddr

    On Linux, kernels later than 2.6.24, it's possible to do:

    $ setcap 'cap_net_bind_service=+ep' /usr/lib/erlang/erts-5.7.4/bin/beam

    The above command grants the capability of binding privileged ports to beam. Note, you have to grant the priviliges to the actual exectuable you are using.

    There are a couple of other options on Linux. One is to use an auxiliary program like authbind http://packages.debian.org/stable/authbind or privbind http://sourceforge.net/projects/privbind/

    These programs are run by root. Yaws writes its temporary JIT compiled files in $HOME/.yaws and this doesn't work that well with authbind/privbind. A non root user will try to write in /root/.yaws. The solution to this is to set the environment variable YAWSHOME. Yaws will then consider that to be HOME rather that $HOME.

    To start yaws under e.g privbind we can do:

    $ sudo YAWSHOME=/tmp/abc privbind -u klacke /home/klacke/bin/yaws \ -c /home/klacke/yaws.conf -i

    The above command starts yaws as user klacke and bind to ports below 1024

    The authbind program is another option: Here is an example:

    touch /etc/authbind/byport/80 touch /etc/authbind/byport/443 chmod 500 /etc/authbind/byport/80 chmod 500 /etc/authbind/byport/443 chown bob /etc/authbind/byport/80 chown bob /etc/authbind/byport/443 YAWSHOME=/home/bob authbind yaws -c /home/bob/yaws.conf -i

    Here is a description on how to do this on MacOs X. It's not exactly the same, since we're still binding to non privileged ports. However, edit /etc/sysctl and add:

    net.inet.ip.forwarding=1
    

    Then with ipfw as the firewall (turn off the gui firewall in system preferences and manage own rules) use the ipfw rules like these - for testing on your own box use something like:

    ipfw add fwd 127.0.0.1,8080 tcp from any to 127.0.0.1 dst-port 80 in
    ipfw add fwd 127.0.0.1,8443 tcp from any to 127.0.0.1 dst-port 443 in
    

    set up yaws to use 8080 and 8443 in yaws.conf and then run as some non root user. When you browse to http://127.0.0.1 or https://127.0.0.1 you will see your pages that are actually on 8080 and 8443 internally but will be forwarded via ipfw forwarding.

    Yet another (more complicated way) for linux users is to hack the kernel. Here is a patch I did for some version of the 2.6 series kernels .. you get the idea.

    [root@lax]ipv4 > diff -c af_inet.c* *** af_inet.c Wed Feb 23 23:31:35 2005 --- af_inet.c~ Thu Feb 17 18:13:13 2005 *************** *** 423,434 **** snum = ntohs(addr->sin_port); err = -EACCES; - #if 0 - /* removed by klacke */ if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) goto out; - #endif - /* We keep a pair of addresses. rcv_saddr is the one * used by hash lookups, and saddr is used for transmit. --- 423,430 ---- out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/static.html0000664000175000017500000000053512605311413012421 00000000000000 Hyber HYBER LOGO

    nano content


    yaws-2.0.2/www/simple_ex2.yaws0000664000175000017500000000014412605311413013214 00000000000000

    Yesssssss

    out(Arg) -> {html, "

    Hello again

    "}.
    yaws-2.0.2/www/setpcookie.yaws0000664000175000017500000000357112605311413013321 00000000000000 -export([pserv/0]). ensure_pcookie_server() -> case whereis(pcookie_server) of undefined -> proc_lib:start(?MODULE, pserv,[]); _ -> ok end. pserv() -> catch begin register(pcookie_server, self()), T = ets:new(pcookies, [set, public, named_table]), ets:insert(T, {counter, 0}) end, proc_lib:init_ack(ok), pserv_loop(). pserv_loop() -> receive X -> pserv_loop() end. setcookie(A) -> Num = ets:update_counter(pcookies, counter, 1), Data = {(A#arg.headers)#headers.user_agent, calendar:local_time(), inet:peername(A#arg.clisock)}, ets:insert(pcookies, {{cookie, Num}, Data}), yaws_api:set_cookie("pfoobar",integer_to_list(Num), [{path,"/"}]). out(A) -> ensure_pcookie_server(), H = A#arg.headers, C = H#headers.cookie, case C of [Cookie|_] -> case string:tokens(Cookie, [$=]) of ["pfoobar", NumStr] -> Num = list_to_integer(NumStr), %% cookie allready set case ets:lookup(pcookies, {c, Num}) of [{cookie, Data}] -> ok; %% cookie already set [] -> setcookie(A) end; _ -> setcookie(A) end; _ -> setcookie(A) end. out(A) -> {ssi, "TAB.inc", [],[]}.

    Set persistent cookie

    This is the page that set a persistent cookie in the browser. readpcookie.yaws will read the cookie and report persistent information.

    out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/query.yaws0000664000175000017500000000366512605311413012325 00000000000000 out(A) -> {ssi, "TAB.inc", "%%",[{"query", "choosen"}]}.

    The query part of the url

    A url can have an optional query part. This part is passed in the A#arg.querydata which is passed as an argument to the out/1 function.

    We show how to work with the query part of the url through an example, if we have a URL on the form of http://yaws.hyber.org/man.yaws?page=cat a key/value pair is passed to the page. In the above example, we have key=page and its value "cat". The code in the page man.yaws, will read these key/value pairs in the A#arg.querydata and display the man page.

    Assuming a predifined CSS class called box, defined as:

          div.box { border: solid; border-width: thin; width: 90%;
          background: rgb(211, 211, 211)  }
        

    The following code:

    out(A) -> {ehtml,ssi("man.yaws")}. ssi(File) -> {'div',[{class,"box"}], {pre,[], {ssi, File, [],[]}}}.

    will display a man page if invoked with a proper key/value pair in the query part of the URL.

    This fairly convenient way of getting at the query (or POST) is equivalent of the code:

        P = yaws_api:parse_query(A),
        L = case lists:keysearch(page, 1, P) of
                  {value, {page, Page}} ->
                       .....
    

    The querypart of the URL is part as field in the Arg structure. The function parse_query/1 parses the raw data into a key/value list.

    The queryvar(ARG,Key) function returns the value of the variable if it is found in the query part of the request. If the variable is not found or if the variable is unset, the queryvar(ARG,Key) function returns undefined.

    out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/upload0.yaws0000664000175000017500000000132112605311413012507 00000000000000 out(A) -> [{ssi, "TAB.inc", "%%",[{"upload0", "choosen"}]}, {ehtml, {html, [], {'div',[{id, "entry"}], [{h1, [], "Upload a file to the webserver"}, {p, [], ["The code that parses the multipart form data resides in ", {a, [{href, "code.yaws?file=/upload.yaws"}], "upload.yaws"}, "."]}, {br,[],[]}, {hr,[],[]}, {form, [{enctype, "multipart/form-data"}, {method, post}, {action, "/upload.yaws"} ], [{input, [{type, submit}, {value, "Upload"}] ,[]}, {input, [{type,file}, {width, "50"}, {name, "foo"}], []} ]}]}}}, {ssi, "END2",[],[]}]. yaws-2.0.2/www/ssi_ex10000664000175000017500000000002112605311413011530 00000000000000variable a = %a% yaws-2.0.2/www/ybed.erl0000664000175000017500000000103112605311413011663 00000000000000-module(ybed). -compile(export_all). start() -> {ok, spawn(?MODULE, run, [])}. run() -> Id = "embedded", GconfList = [{id, Id}], Docroot = "/tmp", SconfList = [{port, 8888}, {servername, "foobar"}, {listen, {0,0,0,0}}, {docroot, Docroot}], {ok, SCList, GC, ChildSpecs} = yaws_api:embedded_start_conf(Docroot, SconfList, GconfList, Id), [supervisor:start_child(ybed_sup, Ch) || Ch <- ChildSpecs], yaws_api:setconf(GC, SCList), {ok, self()}. yaws-2.0.2/www/post.yaws0000664000175000017500000000362012605311413012134 00000000000000 box(Str) -> {'div',[{class,"box"}], {pre,[], yaws_api:htmlize(Str)}}. fpostvar(A, Key) -> case postvar(A,"lang") of undefined -> "None"; {ok, Val} -> Val end. out(A) -> [{ssi, "TAB.inc", [],[]}, {ehtml, {'div',[{id, "entry"}], [{h2, [],"post.yaws"}, {p,[],[ "This is the ", {tt, [], "post.yaws"}, " file ", "This yaws file gets invoked with POSTed client data. " "This is the data that is submitted from the forms page ", {a, [{href, "form.yaws"}], " form.yaws "}]}, {p, [], ["POST data is naturally organized as a ", {tt, [], "{Key, Value} "}, " list. A call to " "the function ", {tt, [], "yaws_api:parse_post(A) "}, " will parse the POSTed data. and return a key/value list "]}, box(" out(A) -> {ehtml, {pre, [], io_lib:format('~p', [yaws_api:parse_post(A)])}}. "), {p, [], "Produces the following output"}, box(io_lib:format('~p', [yaws_api:parse_post(A)])), {p, [], ["The natural way to extract the \"Variables\" from " " the posted data is to use the function (defined in yaws_api.erl) " " called ", {tt,[], "postvar(Arg,Key) "}]}, {p, [], "Thus the following erlang code: "}, box(" out(A) -> {ehtml, {p,[], [\"The favourite programming language is \", case postvar(A,\"lang\") of undefined -> \"None\"; {ok, Val} -> Val end]}}. "), {p,[], "Produces the following output:"}, {hr,[],[]}, {'div',[{class,"box"}], {p,[], ["The favourite programming language is ", case postvar(A,"lang") of undefined -> "None"; {ok, Val} -> Val end]}} ]}}, {ssi, "END",[],[]}]. yaws-2.0.2/www/cgi-bin/0000775000175000017500000000000012605311413011631 500000000000000yaws-2.0.2/www/cgi-bin/foo.py0000775000175000017500000000012712605311413012711 00000000000000#!/usr/bin/python import cgi print "Content-type: text/html\n\n" print "hi there " yaws-2.0.2/www/favicon.ico0000664000175000017500000000257612605311413012374 00000000000000h( @ÿÿÿþnlm‚‚úA6Ë£¥¤;=9ÒÑÑ¿ª¨üBNj]_õ"áØÒþ""¾ììêVj‚ÞOMÖ3+ë--.èöþ ÞâÒðØSLçÄvj^ÑÞáýdfb ' üüþñàáàúòþöõèññýöéêþûÓÙ×Ö Éhenèîöþþñöý%¾$"ã áèåèÚÚüûúúö ý ÚýþöîúþþúþâæòýêìîðòþêîýýýöþýþúúþþúúþöþúöúþúöþþþOOOO9OBFM2OOOOOOOOOOOO&MMHOOOOOOOOOOOOBNMIOOOOOOOOOOOO&N>OOOOOOOOOOOO3MHOOOOOOOOOO9OOOOOOOOOOH9?=(DOOOOOOOOO&>50A*1?@GOOOOOO$E#' )HOOOOOOJ,( "HGOOO2OI</K .EOIOOHDM O!>GOHL9H:7-G$OINN>O%@LG4N;N.8OCD +06 >>OOO$OOOO@OH>O$yaws-2.0.2/www/cookies.yaws0000664000175000017500000000445712605311413012614 00000000000000 out(A) -> {ssi, "TAB.inc", "%%",[{"cookies", "choosen"}]}.

    Yaws and Cookies

    Cookies are the means in HTTP to assign data to a session. A HTTP session typically consists of many (and sometimes concurrent) TCP connections from the client to the web server. The first time a client arrives to our webserver, we issue the HTTP header Set-Cookie: var=someval. The browser will then in subsequent connections to the same server pass this cookie "var=someval" in its client side Cookie: var=someval header. We can thereby assign state to a session, either through data actualy encoded into the cookie value itself, or by associating server side session data to the cookie.

    Let's do an example where we set a simple cookie, and create a specific erlang process which is then responsible for that session. The cookie value will be a string encoding of the pid handling the session.

    The yaws code in setcookie.yaws sets the cookie in the browser. Note that the call to yaws_api:set_cookie/3 in the example returns a header setting (like {header, HeaderNameAndValue}) from the out/1 function, which directs Yaws to set the specified header in the response to the browser.

    And the yaws code in readcookie.yaws will read the cookie and report some uninteresting session data.

    A correct definition of cookies can be found in RFC 6265

    Set Cookie

    The code to set the cookie looks like:

    out(A) -> {ok, B} = file:read_file(A#arg.docroot ++ "/setcookie.yaws"), {ehtml, {'div', [{class, "box"}], {pre,[], B}}}.

    This is the page that set the cookie in the browser. readcookie.yaws will read the cookie and report persistent information as long as the browser session exists.

    it will set the cookie foobar = <x,y,z>; where the x,y,z string is the textual representation of an actual erlang pid which will be responsible for this session.

    out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/yapp_intro.yaws0000664000175000017500000001642212605311413013337 00000000000000 box(Str) -> {'div',[{class,"box"}], {pre,[], yaws_api:htmlize(Str)}}. tbox(T) -> box(lists:flatten(io_lib:format("~p",[T]))). out(A) -> [{ssi, "TAB.inc", "%%",[{"yapp_intro", "choosen"}]}, {ehtml, {'div', [{id, "entry"}], [{h1, [], "Yaws applications - Yapps"}, {p, [], "Yaws applications, Yapps, are actually ordinary Erlang/OTP " "applications with some optional information in their " ".app files and the web pages in the priv/docroot directory " "as default. The Yaws applications handler takes care of adding, " "and removing, the applications into a running server. " " When anyone access the server with an URL that matches the path for an " " added application, the docroot will be temporarily switched to where the web " " pages for that application are located."}, {h2,[], "Using the application handler"}, {h3,[], "Installing"}, {p, [], ["The application handler is named just yapp and is located in the " "directory yaws/applications/yapp. Yaws itself should have been built first, " "then in the yapp directory we do", {ol, [],[ {li,[],{pre,[], "make"}}, {li,[],[{pre,[], "make docs"}," - if we want documentation"]}, {li,[],[{pre,[], "make install"}," - unless yaws was installed with make local_install"]} ] }]}, {h3,[], "Setting up yaws.conf"}, {p,[], "First we include the ebin directory of the yapp handler " "application by adding the line " }, box("ebin_dir = //{applications,lib}/yapp/ebin"), {p,[], "The \"applications\" part is used for a local_installed Yaws, and \"lib\"" " for a real installed one. Then we make sure that the yapp handler " " application is started when Yaws is started, by using the runmod directive"}, box("runmod = yapp"), {p,[], "For every virtual server that we want to use yapps we add yapp as an " "arg_rewrite_mod and set the opaque parameter yapp_server_id to a unique " "name."}, box(" port = 8000 listen = 0.0.0.0 docroot = /yawsdocrootpath/www arg_rewrite_mod = yapp yapp_server_id = edo "), {p,[], "The web applications that are configured in the Yapp registry will be loaded " "into Yaws configuration when the yapp application is started. A prerequisite " "is that the applications are found in the Erlang code loader path. There is " "also an option to define yapps in yaws.conf for every server directly by using " "the opaque parameter bootstrap_yapps = webapp1, webapp2 etc. "}, {p,[], "For instance the yapp handler application (named yapp) is a yapp in itself, " "got it?, that provides a web gui to list active yapps and add/remove yapps " "from the registry. But since we can not add itself to the registry before it " "is added we have to bootstrap into the server when Yaws is started. "}, box(" port = 8001 listen = 0.0.0.0 docroot = /docrootpath/www arg_rewrite_mod = yapp yapp_server_id = ido bootstrap_yapps = yapp " ), {h3,[],"Executing"}, {p,[], "The current default Yapp registry implementation uses Mnesia, we have made " "it easy to plug in other future registry implementations by configuring the " "yapp.app file, but Mnesia is recommended to be future proof for clustered " "application servers. In order to use mnesia one has to prepare a schema, " "we start an erlang shell with the same node name as Yaws is using: "}, {p,[],{pre,[], "erl -sname node_name 1> mnesia:create_schema([node()])."}}, {p,[],["(we can leave out the -sname options, then the mnesia schema name will " "be \"nonode@nohost\") then we exit and start yaws with the same name: ", {pre,[],"yaws -sname node_name"}]}, {p,[],["Now we can access the yapp handler web console from a browser with url:", {pre,[],"http://myinternalserver:8001/yapp/"}]}, {h2,[],"Making yapps"}, {p,[], [ "In order to make a \"yapp\" we need to know how to make an ordinary Erlang " "application, that is we will need a directory layout as specified by the ", {a,[{href, "http://www.erlang.org/doc/design_principles/des_princ.html" }], "design principles"}, " and a proper appname.app file in the ebin directory. " "Yaws itself or yapp are standard applications and can serve as introductionary " "examples. "]}, {h3,[], "Internal paths"}, {p,[], "Making paths to other documents in the same web application using root paths " "like href=\"/doc2.html\" will not work since a yapp is always below the top. " "Instead use relative paths href=\"doc2.html\" or use the prepath library " "function in any .yaws file: href=yapp:prepath(A) ++ \"doc2.html\", " "where A is a #arg record."}, {h3,[],"Appmods"}, {p,[], "The yapp handler takes care of throwing in \"private\" appmods for a yapp " "when it is accessed. The appmods modules are put in the applications ebin " "directory as any other Erlang module and configured in the .app file " "with the the environment variable yapp_appmods. For instance; if we " "have a yapp named yappx with root path \"/yappx\" and add: "}, box(" {env, [ {yapp_appmods,[{\"ctrl\",yappx_controller}]} ]}, "), {p,[],"to the env part in the yappx.app file, an access to the URL " "http://servername/yappx/ctrl will cause a call to the " "yappx_controller:out/1 function, while http://servername/yappy/ctrl " "will not do it. " }, {h3,[],"Opaque variables"}, {p,[],[ "In a similar way the yapp handler adds \"private\" opaques for a yapp " "with the the environment variable yapp_opaque. " "As an example ", {a,[{href,"http://erlyweb.org/"}], "ErlyWeb "}, "applications uses both appmods and opaques in yaws.conf. These can " "be put in the .app file instead if one makes a yapp of it:"]}, box(" {application, myapp1, [{description,\"myapp1 is an erlyweb yapp\"}, {vsn,\"0.1\"}, {modules,[]}, {registered, []}, % {mod,{myapp1_app,[]}}, %% Only needed if the application needs to be started {env, [ {yapp_docroot,\"www\"}, {yapp_appmods,[{\"erlyweb\",erlyweb}]}, {yapp_opaque,[{\"appname\",\"myapp1\"}]} ]}, {applications,[kernel,stdlib]}]}. "), {p,[],"Also note that the docroot is www instead of the default priv/docroot in " "ErlyWeb applications."}, {h2,[],"Problems"}, {p,[],"Embedded ssi directives in ehtml parts do not work."} ] } }, {ssi, "END2",[],[]} ]. yaws-2.0.2/www/readpcookie.yaws0000664000175000017500000000241612605311413013436 00000000000000

    Read persistent cookie

    to_integer(S) -> list_to_integer(string:strip(S, both)). out(A) -> H=A#arg.headers, C = H#headers.cookie, L=case yaws_api:find_cookie_val("pfoobar", C) of [] -> f("

    No cookie set from the browser, need to " "visit setpcookie.yaws " "to set the cookie first

    ~n", []); NumStr -> Num = to_integer(NumStr), case ets:lookup(pcookies, {cookie,Num}) of [{{cookie, Num}, Data}] -> f("

    Yes, I read your cookie:it is ~p~n " "Your persistent info is ~n" "

    ~n~p~n

    ~n", [NumStr, Data]); [] -> f("

    You had a cookie,but the data is gone

    ",[]) end end, {html, L}.

    The code to read the cookie, is simple, we get the cookie passed to the yaws code in the #arg structure which is the argument supplied to the out/1 function. The code is:

    out(A) -> {ok, B} = file:read_file(A#arg.docroot ++ "/readpcookie.yaws"), {ehtml, {'div', [{class, "box"}], {pre,[], B}}}. yaws-2.0.2/www/yaws.eps0000664000175000017500000145243212605311413011750 00000000000000%!PS-Adobe-3.1 EPSF-3.0 %ADO_DSC_Encoding: MacOS Roman %%Title: yaws.eps %%Creator: Adobe Illustrator(R) 13.0 %%For: Tomas Selander %%CreationDate: 12/29/11 %%BoundingBox: 0 0 550 40 %%HiResBoundingBox: 0 0 549.4180 39.9268 %%CropBox: 0 0 549.4180 39.9268 %%LanguageLevel: 2 %%DocumentData: Clean7Bit %ADOBeginClientInjection: DocumentHeader "AI11EPS" %%AI8_CreatorVersion: 13.0.1 %AI9_PrintingDataBegin %ADO_BuildNumber: Adobe Illustrator(R) 13.0.1 x420 R agm 4.4379 ct 5.1039 %ADO_ContainsXMP: MainFirst %ADOEndClientInjection: DocumentHeader "AI11EPS" %%Pages: 1 %%DocumentNeededResources: %%DocumentSuppliedResources: procset Adobe_AGM_Image 1.0 0 %%+ procset Adobe_CoolType_Utility_T42 1.0 0 %%+ procset Adobe_CoolType_Utility_MAKEOCF 1.23 0 %%+ procset Adobe_CoolType_Core 2.31 0 %%+ procset Adobe_AGM_Core 2.0 0 %%+ procset Adobe_AGM_Utils 1.0 0 %%DocumentFonts: %%DocumentNeededFonts: %%DocumentNeededFeatures: %%DocumentSuppliedFeatures: %%DocumentProcessColors: Cyan Magenta Yellow Black %%DocumentCustomColors: %%CMYKCustomColor: %%RGBCustomColor: %%EndComments %%BeginDefaults %%ViewingOrientation: 1 0 0 1 %%EndDefaults %%BeginProlog %%BeginResource: procset Adobe_AGM_Utils 1.0 0 %%Version: 1.0 0 %%Copyright: Copyright(C)2000-2006 Adobe Systems, Inc. All Rights Reserved. systemdict/setpacking known {currentpacking true setpacking}if userdict/Adobe_AGM_Utils 73 dict dup begin put /bdf {bind def}bind def /nd{null def}bdf /xdf {exch def}bdf /ldf {load def}bdf /ddf {put}bdf /xddf {3 -1 roll put}bdf /xpt {exch put}bdf /ndf { exch dup where{ pop pop pop }{ xdf }ifelse }def /cdndf { exch dup currentdict exch known{ pop pop }{ exch def }ifelse }def /gx {get exec}bdf /ps_level /languagelevel where{ pop systemdict/languagelevel gx }{ 1 }ifelse def /level2 ps_level 2 ge def /level3 ps_level 3 ge def /ps_version {version cvr}stopped{-1}if def /set_gvm {currentglobal exch setglobal}bdf /reset_gvm {setglobal}bdf /makereadonlyarray { /packedarray where{pop packedarray }{ array astore readonly}ifelse }bdf /map_reserved_ink_name { dup type/stringtype eq{ dup/Red eq{ pop(_Red_) }{ dup/Green eq{ pop(_Green_) }{ dup/Blue eq{ pop(_Blue_) }{ dup()cvn eq{ pop(Process) }if }ifelse }ifelse }ifelse }if }bdf /AGMUTIL_GSTATE 22 dict def /get_gstate { AGMUTIL_GSTATE begin /AGMUTIL_GSTATE_clr_spc currentcolorspace def /AGMUTIL_GSTATE_clr_indx 0 def /AGMUTIL_GSTATE_clr_comps 12 array def mark currentcolor counttomark {AGMUTIL_GSTATE_clr_comps AGMUTIL_GSTATE_clr_indx 3 -1 roll put /AGMUTIL_GSTATE_clr_indx AGMUTIL_GSTATE_clr_indx 1 add def}repeat pop /AGMUTIL_GSTATE_fnt rootfont def /AGMUTIL_GSTATE_lw currentlinewidth def /AGMUTIL_GSTATE_lc currentlinecap def /AGMUTIL_GSTATE_lj currentlinejoin def /AGMUTIL_GSTATE_ml currentmiterlimit def currentdash/AGMUTIL_GSTATE_do xdf/AGMUTIL_GSTATE_da xdf /AGMUTIL_GSTATE_sa currentstrokeadjust def /AGMUTIL_GSTATE_clr_rnd currentcolorrendering def /AGMUTIL_GSTATE_op currentoverprint def /AGMUTIL_GSTATE_bg currentblackgeneration cvlit def /AGMUTIL_GSTATE_ucr currentundercolorremoval cvlit def currentcolortransfer cvlit/AGMUTIL_GSTATE_gy_xfer xdf cvlit/AGMUTIL_GSTATE_b_xfer xdf cvlit/AGMUTIL_GSTATE_g_xfer xdf cvlit/AGMUTIL_GSTATE_r_xfer xdf /AGMUTIL_GSTATE_ht currenthalftone def /AGMUTIL_GSTATE_flt currentflat def end }def /set_gstate { AGMUTIL_GSTATE begin AGMUTIL_GSTATE_clr_spc setcolorspace AGMUTIL_GSTATE_clr_indx{AGMUTIL_GSTATE_clr_comps AGMUTIL_GSTATE_clr_indx 1 sub get /AGMUTIL_GSTATE_clr_indx AGMUTIL_GSTATE_clr_indx 1 sub def}repeat setcolor AGMUTIL_GSTATE_fnt setfont AGMUTIL_GSTATE_lw setlinewidth AGMUTIL_GSTATE_lc setlinecap AGMUTIL_GSTATE_lj setlinejoin AGMUTIL_GSTATE_ml setmiterlimit AGMUTIL_GSTATE_da AGMUTIL_GSTATE_do setdash AGMUTIL_GSTATE_sa setstrokeadjust AGMUTIL_GSTATE_clr_rnd setcolorrendering AGMUTIL_GSTATE_op setoverprint AGMUTIL_GSTATE_bg cvx setblackgeneration AGMUTIL_GSTATE_ucr cvx setundercolorremoval AGMUTIL_GSTATE_r_xfer cvx AGMUTIL_GSTATE_g_xfer cvx AGMUTIL_GSTATE_b_xfer cvx AGMUTIL_GSTATE_gy_xfer cvx setcolortransfer AGMUTIL_GSTATE_ht/HalftoneType get dup 9 eq exch 100 eq or { currenthalftone/HalftoneType get AGMUTIL_GSTATE_ht/HalftoneType get ne { mark AGMUTIL_GSTATE_ht{sethalftone}stopped cleartomark }if }{ AGMUTIL_GSTATE_ht sethalftone }ifelse AGMUTIL_GSTATE_flt setflat end }def /get_gstate_and_matrix { AGMUTIL_GSTATE begin /AGMUTIL_GSTATE_ctm matrix currentmatrix def end get_gstate }def /set_gstate_and_matrix { set_gstate AGMUTIL_GSTATE begin AGMUTIL_GSTATE_ctm setmatrix end }def /AGMUTIL_str256 256 string def /AGMUTIL_src256 256 string def /AGMUTIL_dst64 64 string def /AGMUTIL_srcLen nd /AGMUTIL_ndx nd /AGMUTIL_cpd nd /capture_cpd{ //Adobe_AGM_Utils/AGMUTIL_cpd currentpagedevice ddf }def /thold_halftone { level3 {sethalftone currenthalftone} { dup/HalftoneType get 3 eq { sethalftone currenthalftone }{ begin Width Height mul{ Thresholds read{pop}if }repeat end currenthalftone }ifelse }ifelse }def /rdcmntline { currentfile AGMUTIL_str256 readline pop (%)anchorsearch{pop}if }bdf /filter_cmyk { dup type/filetype ne{ exch()/SubFileDecode filter }{ exch pop } ifelse [ exch { AGMUTIL_src256 readstring pop dup length/AGMUTIL_srcLen exch def /AGMUTIL_ndx 0 def AGMCORE_plate_ndx 4 AGMUTIL_srcLen 1 sub{ 1 index exch get AGMUTIL_dst64 AGMUTIL_ndx 3 -1 roll put /AGMUTIL_ndx AGMUTIL_ndx 1 add def }for pop AGMUTIL_dst64 0 AGMUTIL_ndx getinterval } bind /exec cvx ]cvx }bdf /filter_indexed_devn { cvi Names length mul names_index add Lookup exch get }bdf /filter_devn { 4 dict begin /srcStr xdf /dstStr xdf dup type/filetype ne{ 0()/SubFileDecode filter }if [ exch [ /devicen_colorspace_dict/AGMCORE_gget cvx/begin cvx currentdict/srcStr get/readstring cvx/pop cvx /dup cvx/length cvx 0/gt cvx[ Adobe_AGM_Utils/AGMUTIL_ndx 0/ddf cvx names_index Names length currentdict/srcStr get length 1 sub{ 1/index cvx/exch cvx/get cvx currentdict/dstStr get/AGMUTIL_ndx/load cvx 3 -1/roll cvx/put cvx Adobe_AGM_Utils/AGMUTIL_ndx/AGMUTIL_ndx/load cvx 1/add cvx/ddf cvx }for currentdict/dstStr get 0/AGMUTIL_ndx/load cvx/getinterval cvx ]cvx/if cvx /end cvx ]cvx bind /exec cvx ]cvx end }bdf /AGMUTIL_imagefile nd /read_image_file { AGMUTIL_imagefile 0 setfileposition 10 dict begin /imageDict xdf /imbufLen Width BitsPerComponent mul 7 add 8 idiv def /imbufIdx 0 def /origDataSource imageDict/DataSource get def /origMultipleDataSources imageDict/MultipleDataSources get def /origDecode imageDict/Decode get def /dstDataStr imageDict/Width get colorSpaceElemCnt mul string def imageDict/MultipleDataSources known{MultipleDataSources}{false}ifelse { /imbufCnt imageDict/DataSource get length def /imbufs imbufCnt array def 0 1 imbufCnt 1 sub{ /imbufIdx xdf imbufs imbufIdx imbufLen string put imageDict/DataSource get imbufIdx[AGMUTIL_imagefile imbufs imbufIdx get/readstring cvx/pop cvx]cvx put }for DeviceN_PS2{ imageDict begin /DataSource[DataSource/devn_sep_datasource cvx]cvx def /MultipleDataSources false def /Decode[0 1]def end }if }{ /imbuf imbufLen string def Indexed_DeviceN level3 not and DeviceN_NoneName or{ /srcDataStrs[imageDict begin currentdict/MultipleDataSources known{MultipleDataSources{DataSource length}{1}ifelse}{1}ifelse { Width Decode length 2 div mul cvi string }repeat end]def imageDict begin /DataSource[AGMUTIL_imagefile Decode BitsPerComponent false 1/filter_indexed_devn load dstDataStr srcDataStrs devn_alt_datasource/exec cvx]cvx def /Decode[0 1]def end }{ imageDict/DataSource[1 string dup 0 AGMUTIL_imagefile Decode length 2 idiv string/readstring cvx/pop cvx names_index/get cvx/put cvx]cvx put imageDict/Decode[0 1]put }ifelse }ifelse imageDict exch load exec imageDict/DataSource origDataSource put imageDict/MultipleDataSources origMultipleDataSources put imageDict/Decode origDecode put end }bdf /write_image_file { begin {(AGMUTIL_imagefile)(w+)file}stopped{ false }{ Adobe_AGM_Utils/AGMUTIL_imagefile xddf 2 dict begin /imbufLen Width BitsPerComponent mul 7 add 8 idiv def MultipleDataSources{DataSource 0 get}{DataSource}ifelse type/filetype eq{ /imbuf imbufLen string def }if 1 1 Height MultipleDataSources not{Decode length 2 idiv mul}if{ pop MultipleDataSources{ 0 1 DataSource length 1 sub{ DataSource type dup /arraytype eq{ pop DataSource exch gx }{ /filetype eq{ DataSource exch get imbuf readstring pop }{ DataSource exch get }ifelse }ifelse AGMUTIL_imagefile exch writestring }for }{ DataSource type dup /arraytype eq{ pop DataSource exec }{ /filetype eq{ DataSource imbuf readstring pop }{ DataSource }ifelse }ifelse AGMUTIL_imagefile exch writestring }ifelse }for end true }ifelse end }bdf /close_image_file { AGMUTIL_imagefile closefile(AGMUTIL_imagefile)deletefile }def statusdict/product known userdict/AGMP_current_show known not and{ /pstr statusdict/product get def pstr(HP LaserJet 2200)eq pstr(HP LaserJet 4000 Series)eq or pstr(HP LaserJet 4050 Series )eq or pstr(HP LaserJet 8000 Series)eq or pstr(HP LaserJet 8100 Series)eq or pstr(HP LaserJet 8150 Series)eq or pstr(HP LaserJet 5000 Series)eq or pstr(HP LaserJet 5100 Series)eq or pstr(HP Color LaserJet 4500)eq or pstr(HP Color LaserJet 4600)eq or pstr(HP LaserJet 5Si)eq or pstr(HP LaserJet 1200 Series)eq or pstr(HP LaserJet 1300 Series)eq or pstr(HP LaserJet 4100 Series)eq or { userdict/AGMP_current_show/show load put userdict/show{ currentcolorspace 0 get /Pattern eq {false charpath f} {AGMP_current_show}ifelse }put }if currentdict/pstr undef }if /consumeimagedata { begin AGMIMG_init_common currentdict/MultipleDataSources known not {/MultipleDataSources false def}if MultipleDataSources { DataSource 0 get type dup/filetype eq { 1 dict begin /flushbuffer Width cvi string def 1 1 Height cvi { pop 0 1 DataSource length 1 sub { DataSource exch get flushbuffer readstring pop pop }for }for end }if dup/arraytype eq exch/packedarraytype eq or DataSource 0 get xcheck and { Width Height mul cvi { 0 1 DataSource length 1 sub {dup DataSource exch gx length exch 0 ne{pop}if}for dup 0 eq {pop exit}if sub dup 0 le {exit}if }loop pop }if } { /DataSource load type dup/filetype eq { 1 dict begin /flushbuffer Width Decode length 2 idiv mul cvi string def 1 1 Height{pop DataSource flushbuffer readstring pop pop}for end }if dup/arraytype eq exch/packedarraytype eq or/DataSource load xcheck and { Height Width BitsPerComponent mul 8 BitsPerComponent sub add 8 idiv Decode length 2 idiv mul mul { DataSource length dup 0 eq {pop exit}if sub dup 0 le {exit}if }loop pop }if }ifelse end }bdf /addprocs { 2{/exec load}repeat 3 1 roll [5 1 roll]bind cvx }def /modify_halftone_xfer { currenthalftone dup length dict copy begin currentdict 2 index known{ 1 index load dup length dict copy begin currentdict/TransferFunction known{ /TransferFunction load }{ currenttransfer }ifelse addprocs/TransferFunction xdf currentdict end def currentdict end sethalftone }{ currentdict/TransferFunction known{ /TransferFunction load }{ currenttransfer }ifelse addprocs/TransferFunction xdf currentdict end sethalftone pop }ifelse }def /clonearray { dup xcheck exch dup length array exch Adobe_AGM_Core/AGMCORE_tmp -1 ddf { Adobe_AGM_Core/AGMCORE_tmp 2 copy get 1 add ddf dup type/dicttype eq { Adobe_AGM_Core/AGMCORE_tmp get exch clonedict Adobe_AGM_Core/AGMCORE_tmp 4 -1 roll ddf }if dup type/arraytype eq { Adobe_AGM_Core/AGMCORE_tmp get exch clonearray Adobe_AGM_Core/AGMCORE_tmp 4 -1 roll ddf }if exch dup Adobe_AGM_Core/AGMCORE_tmp get 4 -1 roll put }forall exch{cvx}if }bdf /clonedict { dup length dict begin { dup type/dicttype eq {clonedict}if dup type/arraytype eq {clonearray}if def }forall currentdict end }bdf /DeviceN_PS2 { /currentcolorspace AGMCORE_gget 0 get/DeviceN eq level3 not and }bdf /Indexed_DeviceN { /indexed_colorspace_dict AGMCORE_gget dup null ne{ dup/CSDBase known{ /CSDBase get/CSD get_res/Names known }{ pop false }ifelse }{ pop false }ifelse }bdf /DeviceN_NoneName { /Names where{ pop false Names { (None)eq or }forall }{ false }ifelse }bdf /DeviceN_PS2_inRip_seps { /AGMCORE_in_rip_sep where { pop dup type dup/arraytype eq exch/packedarraytype eq or { dup 0 get/DeviceN eq level3 not and AGMCORE_in_rip_sep and { /currentcolorspace exch AGMCORE_gput false }{ true }ifelse }{ true }ifelse }{ true }ifelse }bdf /base_colorspace_type { dup type/arraytype eq{0 get}if }bdf /currentdistillerparams where{pop currentdistillerparams/CoreDistVersion get 5000 lt}{true}ifelse { /pdfmark_5{cleartomark}bind def }{ /pdfmark_5{pdfmark}bind def }ifelse /ReadBypdfmark_5 { currentfile exch 0 exch/SubFileDecode filter /currentdistillerparams where {pop currentdistillerparams/CoreDistVersion get 5000 lt}{true}ifelse {flushfile cleartomark} {/PUT pdfmark}ifelse }bdf /xpdfm { { dup 0 get/Label eq { aload length[exch 1 add 1 roll/PAGELABEL }{ aload pop [{ThisPage}<<5 -2 roll>>/PUT }ifelse pdfmark_5 }forall }bdf /ds{ Adobe_AGM_Utils begin }bdf /dt{ currentdict Adobe_AGM_Utils eq{ end }if }bdf systemdict/setpacking known {setpacking}if %%EndResource %%BeginResource: procset Adobe_AGM_Core 2.0 0 %%Version: 2.0 0 %%Copyright: Copyright(C)1997-2007 Adobe Systems, Inc. All Rights Reserved. systemdict/setpacking known { currentpacking true setpacking }if userdict/Adobe_AGM_Core 209 dict dup begin put /Adobe_AGM_Core_Id/Adobe_AGM_Core_2.0_0 def /AGMCORE_str256 256 string def /AGMCORE_save nd /AGMCORE_graphicsave nd /AGMCORE_c 0 def /AGMCORE_m 0 def /AGMCORE_y 0 def /AGMCORE_k 0 def /AGMCORE_cmykbuf 4 array def /AGMCORE_screen[currentscreen]cvx def /AGMCORE_tmp 0 def /AGMCORE_&setgray nd /AGMCORE_&setcolor nd /AGMCORE_&setcolorspace nd /AGMCORE_&setcmykcolor nd /AGMCORE_cyan_plate nd /AGMCORE_magenta_plate nd /AGMCORE_yellow_plate nd /AGMCORE_black_plate nd /AGMCORE_plate_ndx nd /AGMCORE_get_ink_data nd /AGMCORE_is_cmyk_sep nd /AGMCORE_host_sep nd /AGMCORE_avoid_L2_sep_space nd /AGMCORE_distilling nd /AGMCORE_composite_job nd /AGMCORE_producing_seps nd /AGMCORE_ps_level -1 def /AGMCORE_ps_version -1 def /AGMCORE_environ_ok nd /AGMCORE_CSD_cache 0 dict def /AGMCORE_currentoverprint false def /AGMCORE_deltaX nd /AGMCORE_deltaY nd /AGMCORE_name nd /AGMCORE_sep_special nd /AGMCORE_err_strings 4 dict def /AGMCORE_cur_err nd /AGMCORE_current_spot_alias false def /AGMCORE_inverting false def /AGMCORE_feature_dictCount nd /AGMCORE_feature_opCount nd /AGMCORE_feature_ctm nd /AGMCORE_ConvertToProcess false def /AGMCORE_Default_CTM matrix def /AGMCORE_Default_PageSize nd /AGMCORE_Default_flatness nd /AGMCORE_currentbg nd /AGMCORE_currentucr nd /AGMCORE_pattern_paint_type 0 def /knockout_unitsq nd currentglobal true setglobal [/CSA/Gradient/Procedure] { /Generic/Category findresource dup length dict copy/Category defineresource pop }forall setglobal /AGMCORE_key_known { where{ /Adobe_AGM_Core_Id known }{ false }ifelse }ndf /flushinput { save 2 dict begin /CompareBuffer 3 -1 roll def /readbuffer 256 string def mark { currentfile readbuffer{readline}stopped {cleartomark mark} { not {pop exit} if CompareBuffer eq {exit} if }ifelse }loop cleartomark end restore }bdf /getspotfunction { AGMCORE_screen exch pop exch pop dup type/dicttype eq{ dup/HalftoneType get 1 eq{ /SpotFunction get }{ dup/HalftoneType get 2 eq{ /GraySpotFunction get }{ pop { abs exch abs 2 copy add 1 gt{ 1 sub dup mul exch 1 sub dup mul add 1 sub }{ dup mul exch dup mul add 1 exch sub }ifelse }bind }ifelse }ifelse }if }def /np {newpath}bdf /clp_npth {clip np}def /eoclp_npth {eoclip np}def /npth_clp {np clip}def /graphic_setup { /AGMCORE_graphicsave save store concat 0 setgray 0 setlinecap 0 setlinejoin 1 setlinewidth []0 setdash 10 setmiterlimit np false setoverprint false setstrokeadjust //Adobe_AGM_Core/spot_alias gx /Adobe_AGM_Image where{ pop Adobe_AGM_Image/spot_alias 2 copy known{ gx }{ pop pop }ifelse }if /sep_colorspace_dict null AGMCORE_gput 100 dict begin /dictstackcount countdictstack def /showpage{}def mark }def /graphic_cleanup { cleartomark dictstackcount 1 countdictstack 1 sub{end}for end AGMCORE_graphicsave restore }def /compose_error_msg { grestoreall initgraphics /Helvetica findfont 10 scalefont setfont /AGMCORE_deltaY 100 def /AGMCORE_deltaX 310 def clippath pathbbox np pop pop 36 add exch 36 add exch moveto 0 AGMCORE_deltaY rlineto AGMCORE_deltaX 0 rlineto 0 AGMCORE_deltaY neg rlineto AGMCORE_deltaX neg 0 rlineto closepath 0 AGMCORE_&setgray gsave 1 AGMCORE_&setgray fill grestore 1 setlinewidth gsave stroke grestore currentpoint AGMCORE_deltaY 15 sub add exch 8 add exch moveto /AGMCORE_deltaY 12 def /AGMCORE_tmp 0 def AGMCORE_err_strings exch get { dup 32 eq { pop AGMCORE_str256 0 AGMCORE_tmp getinterval stringwidth pop currentpoint pop add AGMCORE_deltaX 28 add gt { currentpoint AGMCORE_deltaY sub exch pop clippath pathbbox pop pop pop 44 add exch moveto }if AGMCORE_str256 0 AGMCORE_tmp getinterval show( )show 0 1 AGMCORE_str256 length 1 sub { AGMCORE_str256 exch 0 put }for /AGMCORE_tmp 0 def }{ AGMCORE_str256 exch AGMCORE_tmp xpt /AGMCORE_tmp AGMCORE_tmp 1 add def }ifelse }forall }bdf /AGMCORE_CMYKDeviceNColorspaces[ [/Separation/None/DeviceCMYK{0 0 0}] [/Separation(Black)/DeviceCMYK{0 0 0 4 -1 roll}bind] [/Separation(Yellow)/DeviceCMYK{0 0 3 -1 roll 0}bind] [/DeviceN[(Yellow)(Black)]/DeviceCMYK{0 0 4 2 roll}bind] [/Separation(Magenta)/DeviceCMYK{0 exch 0 0}bind] [/DeviceN[(Magenta)(Black)]/DeviceCMYK{0 3 1 roll 0 exch}bind] [/DeviceN[(Magenta)(Yellow)]/DeviceCMYK{0 3 1 roll 0}bind] [/DeviceN[(Magenta)(Yellow)(Black)]/DeviceCMYK{0 4 1 roll}bind] [/Separation(Cyan)/DeviceCMYK{0 0 0}] [/DeviceN[(Cyan)(Black)]/DeviceCMYK{0 0 3 -1 roll}bind] [/DeviceN[(Cyan)(Yellow)]/DeviceCMYK{0 exch 0}bind] [/DeviceN[(Cyan)(Yellow)(Black)]/DeviceCMYK{0 3 1 roll}bind] [/DeviceN[(Cyan)(Magenta)]/DeviceCMYK{0 0}] [/DeviceN[(Cyan)(Magenta)(Black)]/DeviceCMYK{0 exch}bind] [/DeviceN[(Cyan)(Magenta)(Yellow)]/DeviceCMYK{0}] [/DeviceCMYK] ]def /ds{ Adobe_AGM_Core begin /currentdistillerparams where { pop currentdistillerparams/CoreDistVersion get 5000 lt {<>setdistillerparams}if }if /AGMCORE_ps_version xdf /AGMCORE_ps_level xdf errordict/AGM_handleerror known not{ errordict/AGM_handleerror errordict/handleerror get put errordict/handleerror{ Adobe_AGM_Core begin $error/newerror get AGMCORE_cur_err null ne and{ $error/newerror false put AGMCORE_cur_err compose_error_msg }if $error/newerror true put end errordict/AGM_handleerror get exec }bind put }if /AGMCORE_environ_ok ps_level AGMCORE_ps_level ge ps_version AGMCORE_ps_version ge and AGMCORE_ps_level -1 eq or def AGMCORE_environ_ok not {/AGMCORE_cur_err/AGMCORE_bad_environ def}if /AGMCORE_&setgray systemdict/setgray get def level2{ /AGMCORE_&setcolor systemdict/setcolor get def /AGMCORE_&setcolorspace systemdict/setcolorspace get def }if /AGMCORE_currentbg currentblackgeneration def /AGMCORE_currentucr currentundercolorremoval def /AGMCORE_Default_flatness currentflat def /AGMCORE_distilling /product where{ pop systemdict/setdistillerparams known product(Adobe PostScript Parser)ne and }{ false }ifelse def /AGMCORE_GSTATE AGMCORE_key_known not{ /AGMCORE_GSTATE 21 dict def /AGMCORE_tmpmatrix matrix def /AGMCORE_gstack 32 array def /AGMCORE_gstackptr 0 def /AGMCORE_gstacksaveptr 0 def /AGMCORE_gstackframekeys 14 def /AGMCORE_&gsave/gsave ldf /AGMCORE_&grestore/grestore ldf /AGMCORE_&grestoreall/grestoreall ldf /AGMCORE_&save/save ldf /AGMCORE_&setoverprint/setoverprint ldf /AGMCORE_gdictcopy{ begin {def}forall end }def /AGMCORE_gput{ AGMCORE_gstack AGMCORE_gstackptr get 3 1 roll put }def /AGMCORE_gget{ AGMCORE_gstack AGMCORE_gstackptr get exch get }def /gsave{ AGMCORE_&gsave AGMCORE_gstack AGMCORE_gstackptr get AGMCORE_gstackptr 1 add dup 32 ge{limitcheck}if /AGMCORE_gstackptr exch store AGMCORE_gstack AGMCORE_gstackptr get AGMCORE_gdictcopy }def /grestore{ AGMCORE_&grestore AGMCORE_gstackptr 1 sub dup AGMCORE_gstacksaveptr lt{1 add}if dup AGMCORE_gstack exch get dup/AGMCORE_currentoverprint known {/AGMCORE_currentoverprint get setoverprint}{pop}ifelse /AGMCORE_gstackptr exch store }def /grestoreall{ AGMCORE_&grestoreall /AGMCORE_gstackptr AGMCORE_gstacksaveptr store }def /save{ AGMCORE_&save AGMCORE_gstack AGMCORE_gstackptr get AGMCORE_gstackptr 1 add dup 32 ge{limitcheck}if /AGMCORE_gstackptr exch store /AGMCORE_gstacksaveptr AGMCORE_gstackptr store AGMCORE_gstack AGMCORE_gstackptr get AGMCORE_gdictcopy }def /setoverprint{ dup/AGMCORE_currentoverprint exch AGMCORE_gput AGMCORE_&setoverprint }def 0 1 AGMCORE_gstack length 1 sub{ AGMCORE_gstack exch AGMCORE_gstackframekeys dict put }for }if level3/AGMCORE_&sysshfill AGMCORE_key_known not and { /AGMCORE_&sysshfill systemdict/shfill get def /AGMCORE_&sysmakepattern systemdict/makepattern get def /AGMCORE_&usrmakepattern/makepattern load def }if /currentcmykcolor[0 0 0 0]AGMCORE_gput /currentstrokeadjust false AGMCORE_gput /currentcolorspace[/DeviceGray]AGMCORE_gput /sep_tint 0 AGMCORE_gput /devicen_tints[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]AGMCORE_gput /sep_colorspace_dict null AGMCORE_gput /devicen_colorspace_dict null AGMCORE_gput /indexed_colorspace_dict null AGMCORE_gput /currentcolor_intent()AGMCORE_gput /customcolor_tint 1 AGMCORE_gput /absolute_colorimetric_crd null AGMCORE_gput /relative_colorimetric_crd null AGMCORE_gput /saturation_crd null AGMCORE_gput /perceptual_crd null AGMCORE_gput currentcolortransfer cvlit/AGMCore_gray_xfer xdf cvlit/AGMCore_b_xfer xdf cvlit/AGMCore_g_xfer xdf cvlit/AGMCore_r_xfer xdf << /MaxPatternItem currentsystemparams/MaxPatternCache get >> setuserparams end }def /ps { /setcmykcolor where{ pop Adobe_AGM_Core/AGMCORE_&setcmykcolor/setcmykcolor load put }if Adobe_AGM_Core begin /setcmykcolor { 4 copy AGMCORE_cmykbuf astore/currentcmykcolor exch AGMCORE_gput 1 sub 4 1 roll 3{ 3 index add neg dup 0 lt{ pop 0 }if 3 1 roll }repeat setrgbcolor pop }ndf /currentcmykcolor { /currentcmykcolor AGMCORE_gget aload pop }ndf /setoverprint {pop}ndf /currentoverprint {false}ndf /AGMCORE_cyan_plate 1 0 0 0 test_cmyk_color_plate def /AGMCORE_magenta_plate 0 1 0 0 test_cmyk_color_plate def /AGMCORE_yellow_plate 0 0 1 0 test_cmyk_color_plate def /AGMCORE_black_plate 0 0 0 1 test_cmyk_color_plate def /AGMCORE_plate_ndx AGMCORE_cyan_plate{ 0 }{ AGMCORE_magenta_plate{ 1 }{ AGMCORE_yellow_plate{ 2 }{ AGMCORE_black_plate{ 3 }{ 4 }ifelse }ifelse }ifelse }ifelse def /AGMCORE_have_reported_unsupported_color_space false def /AGMCORE_report_unsupported_color_space { AGMCORE_have_reported_unsupported_color_space false eq { (Warning: Job contains content that cannot be separated with on-host methods. This content appears on the black plate, and knocks out all other plates.)== Adobe_AGM_Core/AGMCORE_have_reported_unsupported_color_space true ddf }if }def /AGMCORE_composite_job AGMCORE_cyan_plate AGMCORE_magenta_plate and AGMCORE_yellow_plate and AGMCORE_black_plate and def /AGMCORE_in_rip_sep /AGMCORE_in_rip_sep where{ pop AGMCORE_in_rip_sep }{ AGMCORE_distilling { false }{ userdict/Adobe_AGM_OnHost_Seps known{ false }{ level2{ currentpagedevice/Separations 2 copy known{ get }{ pop pop false }ifelse }{ false }ifelse }ifelse }ifelse }ifelse def /AGMCORE_producing_seps AGMCORE_composite_job not AGMCORE_in_rip_sep or def /AGMCORE_host_sep AGMCORE_producing_seps AGMCORE_in_rip_sep not and def /AGM_preserve_spots /AGM_preserve_spots where{ pop AGM_preserve_spots }{ AGMCORE_distilling AGMCORE_producing_seps or }ifelse def /AGM_is_distiller_preserving_spotimages { currentdistillerparams/PreserveOverprintSettings known { currentdistillerparams/PreserveOverprintSettings get { currentdistillerparams/ColorConversionStrategy known { currentdistillerparams/ColorConversionStrategy get /sRGB ne }{ true }ifelse }{ false }ifelse }{ false }ifelse }def /convert_spot_to_process where{pop}{ /convert_spot_to_process { //Adobe_AGM_Core begin dup map_alias{ /Name get exch pop }if dup dup(None)eq exch(All)eq or { pop false }{ AGMCORE_host_sep { gsave 1 0 0 0 setcmykcolor currentgray 1 exch sub 0 1 0 0 setcmykcolor currentgray 1 exch sub 0 0 1 0 setcmykcolor currentgray 1 exch sub 0 0 0 1 setcmykcolor currentgray 1 exch sub add add add 0 eq { pop false }{ false setoverprint current_spot_alias false set_spot_alias 1 1 1 1 6 -1 roll findcmykcustomcolor 1 setcustomcolor set_spot_alias currentgray 1 ne }ifelse grestore }{ AGMCORE_distilling { pop AGM_is_distiller_preserving_spotimages not }{ //Adobe_AGM_Core/AGMCORE_name xddf false //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 0 eq AGMUTIL_cpd/OverrideSeparations known and { AGMUTIL_cpd/OverrideSeparations get { /HqnSpots/ProcSet resourcestatus { pop pop pop true }if }if }if { AGMCORE_name/HqnSpots/ProcSet findresource/TestSpot gx not }{ gsave [/Separation AGMCORE_name/DeviceGray{}]AGMCORE_&setcolorspace false AGMUTIL_cpd/SeparationColorNames 2 copy known { get {AGMCORE_name eq or}forall not }{ pop pop pop true }ifelse grestore }ifelse }ifelse }ifelse }ifelse end }def }ifelse /convert_to_process where{pop}{ /convert_to_process { dup length 0 eq { pop false }{ AGMCORE_host_sep { dup true exch { dup(Cyan)eq exch dup(Magenta)eq 3 -1 roll or exch dup(Yellow)eq 3 -1 roll or exch dup(Black)eq 3 -1 roll or {pop} {convert_spot_to_process and}ifelse } forall { true exch { dup(Cyan)eq exch dup(Magenta)eq 3 -1 roll or exch dup(Yellow)eq 3 -1 roll or exch (Black)eq or and }forall not }{pop false}ifelse }{ false exch { /PhotoshopDuotoneList where{pop false}{true}ifelse { dup(Cyan)eq exch dup(Magenta)eq 3 -1 roll or exch dup(Yellow)eq 3 -1 roll or exch dup(Black)eq 3 -1 roll or {pop} {convert_spot_to_process or}ifelse } { convert_spot_to_process or } ifelse } forall }ifelse }ifelse }def }ifelse /AGMCORE_avoid_L2_sep_space version cvr 2012 lt level2 and AGMCORE_producing_seps not and def /AGMCORE_is_cmyk_sep AGMCORE_cyan_plate AGMCORE_magenta_plate or AGMCORE_yellow_plate or AGMCORE_black_plate or def /AGM_avoid_0_cmyk where{ pop AGM_avoid_0_cmyk }{ AGM_preserve_spots userdict/Adobe_AGM_OnHost_Seps known userdict/Adobe_AGM_InRip_Seps known or not and }ifelse { /setcmykcolor[ { 4 copy add add add 0 eq currentoverprint and{ pop 0.0005 }if }/exec cvx /AGMCORE_&setcmykcolor load dup type/operatortype ne{ /exec cvx }if ]cvx def }if /AGMCORE_IsSeparationAProcessColor { dup(Cyan)eq exch dup(Magenta)eq exch dup(Yellow)eq exch(Black)eq or or or }def AGMCORE_host_sep{ /setcolortransfer { AGMCORE_cyan_plate{ pop pop pop }{ AGMCORE_magenta_plate{ 4 3 roll pop pop pop }{ AGMCORE_yellow_plate{ 4 2 roll pop pop pop }{ 4 1 roll pop pop pop }ifelse }ifelse }ifelse settransfer } def /AGMCORE_get_ink_data AGMCORE_cyan_plate{ {pop pop pop} }{ AGMCORE_magenta_plate{ {4 3 roll pop pop pop} }{ AGMCORE_yellow_plate{ {4 2 roll pop pop pop} }{ {4 1 roll pop pop pop} }ifelse }ifelse }ifelse def /AGMCORE_RemoveProcessColorNames { 1 dict begin /filtername { dup/Cyan eq 1 index(Cyan)eq or {pop(_cyan_)}if dup/Magenta eq 1 index(Magenta)eq or {pop(_magenta_)}if dup/Yellow eq 1 index(Yellow)eq or {pop(_yellow_)}if dup/Black eq 1 index(Black)eq or {pop(_black_)}if }def dup type/arraytype eq {[exch{filtername}forall]} {filtername}ifelse end }def level3{ /AGMCORE_IsCurrentColor { dup AGMCORE_IsSeparationAProcessColor { AGMCORE_plate_ndx 0 eq {dup(Cyan)eq exch/Cyan eq or}if AGMCORE_plate_ndx 1 eq {dup(Magenta)eq exch/Magenta eq or}if AGMCORE_plate_ndx 2 eq {dup(Yellow)eq exch/Yellow eq or}if AGMCORE_plate_ndx 3 eq {dup(Black)eq exch/Black eq or}if AGMCORE_plate_ndx 4 eq {pop false}if }{ gsave false setoverprint current_spot_alias false set_spot_alias 1 1 1 1 6 -1 roll findcmykcustomcolor 1 setcustomcolor set_spot_alias currentgray 1 ne grestore }ifelse }def /AGMCORE_filter_functiondatasource { 5 dict begin /data_in xdf data_in type/stringtype eq { /ncomp xdf /comp xdf /string_out data_in length ncomp idiv string def 0 ncomp data_in length 1 sub { string_out exch dup ncomp idiv exch data_in exch ncomp getinterval comp get 255 exch sub put }for string_out }{ string/string_in xdf /string_out 1 string def /component xdf [ data_in string_in/readstring cvx [component/get cvx 255/exch cvx/sub cvx string_out/exch cvx 0/exch cvx/put cvx string_out]cvx [/pop cvx()]cvx/ifelse cvx ]cvx/ReusableStreamDecode filter }ifelse end }def /AGMCORE_separateShadingFunction { 2 dict begin /paint? xdf /channel xdf dup type/dicttype eq { begin FunctionType 0 eq { /DataSource channel Range length 2 idiv DataSource AGMCORE_filter_functiondatasource def currentdict/Decode known {/Decode Decode channel 2 mul 2 getinterval def}if paint? not {/Decode[1 1]def}if }if FunctionType 2 eq { paint? { /C0[C0 channel get 1 exch sub]def /C1[C1 channel get 1 exch sub]def }{ /C0[1]def /C1[1]def }ifelse }if FunctionType 3 eq { /Functions[Functions{channel paint? AGMCORE_separateShadingFunction}forall]def }if currentdict/Range known {/Range[0 1]def}if currentdict end}{ channel get 0 paint? AGMCORE_separateShadingFunction }ifelse end }def /AGMCORE_separateShading { 3 -1 roll begin currentdict/Function known { currentdict/Background known {[1 index{Background 3 index get 1 exch sub}{1}ifelse]/Background xdf}if Function 3 1 roll AGMCORE_separateShadingFunction/Function xdf /ColorSpace[/DeviceGray]def }{ ColorSpace dup type/arraytype eq{0 get}if/DeviceCMYK eq { /ColorSpace[/DeviceN[/_cyan_/_magenta_/_yellow_/_black_]/DeviceCMYK{}]def }{ ColorSpace dup 1 get AGMCORE_RemoveProcessColorNames 1 exch put }ifelse ColorSpace 0 get/Separation eq { { [1/exch cvx/sub cvx]cvx }{ [/pop cvx 1]cvx }ifelse ColorSpace 3 3 -1 roll put pop }{ { [exch ColorSpace 1 get length 1 sub exch sub/index cvx 1/exch cvx/sub cvx ColorSpace 1 get length 1 add 1/roll cvx ColorSpace 1 get length{/pop cvx}repeat]cvx }{ pop[ColorSpace 1 get length{/pop cvx}repeat cvx 1]cvx }ifelse ColorSpace 3 3 -1 roll bind put }ifelse ColorSpace 2/DeviceGray put }ifelse end }def /AGMCORE_separateShadingDict { dup/ColorSpace get dup type/arraytype ne {[exch]}if dup 0 get/DeviceCMYK eq { exch begin currentdict AGMCORE_cyan_plate {0 true}if AGMCORE_magenta_plate {1 true}if AGMCORE_yellow_plate {2 true}if AGMCORE_black_plate {3 true}if AGMCORE_plate_ndx 4 eq {0 false}if dup not currentoverprint and {/AGMCORE_ignoreshade true def}if AGMCORE_separateShading currentdict end exch }if dup 0 get/Separation eq { exch begin ColorSpace 1 get dup/None ne exch/All ne and { ColorSpace 1 get AGMCORE_IsCurrentColor AGMCORE_plate_ndx 4 lt and ColorSpace 1 get AGMCORE_IsSeparationAProcessColor not and { ColorSpace 2 get dup type/arraytype eq{0 get}if/DeviceCMYK eq { /ColorSpace [ /Separation ColorSpace 1 get /DeviceGray [ ColorSpace 3 get/exec cvx 4 AGMCORE_plate_ndx sub -1/roll cvx 4 1/roll cvx 3[/pop cvx]cvx/repeat cvx 1/exch cvx/sub cvx ]cvx ]def }{ AGMCORE_report_unsupported_color_space AGMCORE_black_plate not { currentdict 0 false AGMCORE_separateShading }if }ifelse }{ currentdict ColorSpace 1 get AGMCORE_IsCurrentColor 0 exch dup not currentoverprint and {/AGMCORE_ignoreshade true def}if AGMCORE_separateShading }ifelse }if currentdict end exch }if dup 0 get/DeviceN eq { exch begin ColorSpace 1 get convert_to_process { ColorSpace 2 get dup type/arraytype eq{0 get}if/DeviceCMYK eq { /ColorSpace [ /DeviceN ColorSpace 1 get /DeviceGray [ ColorSpace 3 get/exec cvx 4 AGMCORE_plate_ndx sub -1/roll cvx 4 1/roll cvx 3[/pop cvx]cvx/repeat cvx 1/exch cvx/sub cvx ]cvx ]def }{ AGMCORE_report_unsupported_color_space AGMCORE_black_plate not { currentdict 0 false AGMCORE_separateShading /ColorSpace[/DeviceGray]def }if }ifelse }{ currentdict false -1 ColorSpace 1 get { AGMCORE_IsCurrentColor { 1 add exch pop true exch exit }if 1 add }forall exch dup not currentoverprint and {/AGMCORE_ignoreshade true def}if AGMCORE_separateShading }ifelse currentdict end exch }if dup 0 get dup/DeviceCMYK eq exch dup/Separation eq exch/DeviceN eq or or not { exch begin ColorSpace dup type/arraytype eq {0 get}if /DeviceGray ne { AGMCORE_report_unsupported_color_space AGMCORE_black_plate not { ColorSpace 0 get/CIEBasedA eq { /ColorSpace[/Separation/_ciebaseda_/DeviceGray{}]def }if ColorSpace 0 get dup/CIEBasedABC eq exch dup/CIEBasedDEF eq exch/DeviceRGB eq or or { /ColorSpace[/DeviceN[/_red_/_green_/_blue_]/DeviceRGB{}]def }if ColorSpace 0 get/CIEBasedDEFG eq { /ColorSpace[/DeviceN[/_cyan_/_magenta_/_yellow_/_black_]/DeviceCMYK{}]def }if currentdict 0 false AGMCORE_separateShading }if }if currentdict end exch }if pop dup/AGMCORE_ignoreshade known { begin /ColorSpace[/Separation(None)/DeviceGray{}]def currentdict end }if }def /shfill { AGMCORE_separateShadingDict dup/AGMCORE_ignoreshade known {pop} {AGMCORE_&sysshfill}ifelse }def /makepattern { exch dup/PatternType get 2 eq { clonedict begin /Shading Shading AGMCORE_separateShadingDict def Shading/AGMCORE_ignoreshade known currentdict end exch {pop<>}if exch AGMCORE_&sysmakepattern }{ exch AGMCORE_&usrmakepattern }ifelse }def }if }if AGMCORE_in_rip_sep{ /setcustomcolor { exch aload pop dup 7 1 roll inRip_spot_has_ink not { 4{4 index mul 4 1 roll} repeat /DeviceCMYK setcolorspace 6 -2 roll pop pop }{ //Adobe_AGM_Core begin /AGMCORE_k xdf/AGMCORE_y xdf/AGMCORE_m xdf/AGMCORE_c xdf end [/Separation 4 -1 roll/DeviceCMYK {dup AGMCORE_c mul exch dup AGMCORE_m mul exch dup AGMCORE_y mul exch AGMCORE_k mul} ] setcolorspace }ifelse setcolor }ndf /setseparationgray { [/Separation(All)/DeviceGray{}]setcolorspace_opt 1 exch sub setcolor }ndf }{ /setseparationgray { AGMCORE_&setgray }ndf }ifelse /findcmykcustomcolor { 5 makereadonlyarray }ndf /setcustomcolor { exch aload pop pop 4{4 index mul 4 1 roll}repeat setcmykcolor pop }ndf /has_color /colorimage where{ AGMCORE_producing_seps{ pop true }{ systemdict eq }ifelse }{ false }ifelse def /map_index { 1 index mul exch getinterval{255 div}forall }bdf /map_indexed_devn { Lookup Names length 3 -1 roll cvi map_index }bdf /n_color_components { base_colorspace_type dup/DeviceGray eq{ pop 1 }{ /DeviceCMYK eq{ 4 }{ 3 }ifelse }ifelse }bdf level2{ /mo/moveto ldf /li/lineto ldf /cv/curveto ldf /knockout_unitsq { 1 setgray 0 0 1 1 rectfill }def level2/setcolorspace AGMCORE_key_known not and{ /AGMCORE_&&&setcolorspace/setcolorspace ldf /AGMCORE_ReplaceMappedColor { dup type dup/arraytype eq exch/packedarraytype eq or { /AGMCORE_SpotAliasAry2 where{ begin dup 0 get dup/Separation eq { pop dup length array copy dup dup 1 get current_spot_alias { dup map_alias { false set_spot_alias dup 1 exch setsepcolorspace true set_spot_alias begin /sep_colorspace_dict currentdict AGMCORE_gput pop pop pop [ /Separation Name CSA map_csa MappedCSA /sep_colorspace_proc load ] dup Name end }if }if map_reserved_ink_name 1 xpt }{ /DeviceN eq { dup length array copy dup dup 1 get[ exch{ current_spot_alias{ dup map_alias{ /Name get exch pop }if }if map_reserved_ink_name }forall ]1 xpt }if }ifelse end }if }if }def /setcolorspace { dup type dup/arraytype eq exch/packedarraytype eq or { dup 0 get/Indexed eq { AGMCORE_distilling { /PhotoshopDuotoneList where { pop false }{ true }ifelse }{ true }ifelse { aload pop 3 -1 roll AGMCORE_ReplaceMappedColor 3 1 roll 4 array astore }if }{ AGMCORE_ReplaceMappedColor }ifelse }if DeviceN_PS2_inRip_seps{AGMCORE_&&&setcolorspace}if }def }if }{ /adj { currentstrokeadjust{ transform 0.25 sub round 0.25 add exch 0.25 sub round 0.25 add exch itransform }if }def /mo{ adj moveto }def /li{ adj lineto }def /cv{ 6 2 roll adj 6 2 roll adj 6 2 roll adj curveto }def /knockout_unitsq { 1 setgray 8 8 1[8 0 0 8 0 0]{}image }def /currentstrokeadjust{ /currentstrokeadjust AGMCORE_gget }def /setstrokeadjust{ /currentstrokeadjust exch AGMCORE_gput }def /setcolorspace { /currentcolorspace exch AGMCORE_gput }def /currentcolorspace { /currentcolorspace AGMCORE_gget }def /setcolor_devicecolor { base_colorspace_type dup/DeviceGray eq{ pop setgray }{ /DeviceCMYK eq{ setcmykcolor }{ setrgbcolor }ifelse }ifelse }def /setcolor { currentcolorspace 0 get dup/DeviceGray ne{ dup/DeviceCMYK ne{ dup/DeviceRGB ne{ dup/Separation eq{ pop currentcolorspace 3 gx currentcolorspace 2 get }{ dup/Indexed eq{ pop currentcolorspace 3 get dup type/stringtype eq{ currentcolorspace 1 get n_color_components 3 -1 roll map_index }{ exec }ifelse currentcolorspace 1 get }{ /AGMCORE_cur_err/AGMCORE_invalid_color_space def AGMCORE_invalid_color_space }ifelse }ifelse }if }if }if setcolor_devicecolor }def }ifelse /sop/setoverprint ldf /lw/setlinewidth ldf /lc/setlinecap ldf /lj/setlinejoin ldf /ml/setmiterlimit ldf /dsh/setdash ldf /sadj/setstrokeadjust ldf /gry/setgray ldf /rgb/setrgbcolor ldf /cmyk[ /currentcolorspace[/DeviceCMYK]/AGMCORE_gput cvx /setcmykcolor load dup type/operatortype ne{/exec cvx}if ]cvx bdf level3 AGMCORE_host_sep not and{ /nzopmsc{ 6 dict begin /kk exch def /yy exch def /mm exch def /cc exch def /sum 0 def cc 0 ne{/sum sum 2#1000 or def cc}if mm 0 ne{/sum sum 2#0100 or def mm}if yy 0 ne{/sum sum 2#0010 or def yy}if kk 0 ne{/sum sum 2#0001 or def kk}if AGMCORE_CMYKDeviceNColorspaces sum get setcolorspace sum 0 eq{0}if end setcolor }bdf }{ /nzopmsc/cmyk ldf }ifelse /sep/setsepcolor ldf /devn/setdevicencolor ldf /idx/setindexedcolor ldf /colr/setcolor ldf /csacrd/set_csa_crd ldf /sepcs/setsepcolorspace ldf /devncs/setdevicencolorspace ldf /idxcs/setindexedcolorspace ldf /cp/closepath ldf /clp/clp_npth ldf /eclp/eoclp_npth ldf /f/fill ldf /ef/eofill ldf /@/stroke ldf /nclp/npth_clp ldf /gset/graphic_setup ldf /gcln/graphic_cleanup ldf /ct/concat ldf /cf/currentfile ldf /fl/filter ldf /rs/readstring ldf /AGMCORE_def_ht currenthalftone def /clonedict Adobe_AGM_Utils begin/clonedict load end def /clonearray Adobe_AGM_Utils begin/clonearray load end def currentdict{ dup xcheck 1 index type dup/arraytype eq exch/packedarraytype eq or and{ bind }if def }forall /getrampcolor { /indx exch def 0 1 NumComp 1 sub { dup Samples exch get dup type/stringtype eq{indx get}if exch Scaling exch get aload pop 3 1 roll mul add }for ColorSpaceFamily/Separation eq {sep} { ColorSpaceFamily/DeviceN eq {devn}{setcolor}ifelse }ifelse }bdf /sssetbackground{ aload pop ColorSpaceFamily/Separation eq {sep} { ColorSpaceFamily/DeviceN eq {devn}{setcolor}ifelse }ifelse }bdf /RadialShade { 40 dict begin /ColorSpaceFamily xdf /background xdf /ext1 xdf /ext0 xdf /BBox xdf /r2 xdf /c2y xdf /c2x xdf /r1 xdf /c1y xdf /c1x xdf /rampdict xdf /setinkoverprint where{pop/setinkoverprint{pop}def}if gsave BBox length 0 gt { np BBox 0 get BBox 1 get moveto BBox 2 get BBox 0 get sub 0 rlineto 0 BBox 3 get BBox 1 get sub rlineto BBox 2 get BBox 0 get sub neg 0 rlineto closepath clip np }if c1x c2x eq { c1y c2y lt{/theta 90 def}{/theta 270 def}ifelse }{ /slope c2y c1y sub c2x c1x sub div def /theta slope 1 atan def c2x c1x lt c2y c1y ge and{/theta theta 180 sub def}if c2x c1x lt c2y c1y lt and{/theta theta 180 add def}if }ifelse gsave clippath c1x c1y translate theta rotate -90 rotate {pathbbox}stopped {0 0 0 0}if /yMax xdf /xMax xdf /yMin xdf /xMin xdf grestore xMax xMin eq yMax yMin eq or { grestore end }{ /max{2 copy gt{pop}{exch pop}ifelse}bdf /min{2 copy lt{pop}{exch pop}ifelse}bdf rampdict begin 40 dict begin background length 0 gt{background sssetbackground gsave clippath fill grestore}if gsave c1x c1y translate theta rotate -90 rotate /c2y c1x c2x sub dup mul c1y c2y sub dup mul add sqrt def /c1y 0 def /c1x 0 def /c2x 0 def ext0 { 0 getrampcolor c2y r2 add r1 sub 0.0001 lt { c1x c1y r1 360 0 arcn pathbbox /aymax exch def /axmax exch def /aymin exch def /axmin exch def /bxMin xMin axmin min def /byMin yMin aymin min def /bxMax xMax axmax max def /byMax yMax aymax max def bxMin byMin moveto bxMax byMin lineto bxMax byMax lineto bxMin byMax lineto bxMin byMin lineto eofill }{ c2y r1 add r2 le { c1x c1y r1 0 360 arc fill } { c2x c2y r2 0 360 arc fill r1 r2 eq { /p1x r1 neg def /p1y c1y def /p2x r1 def /p2y c1y def p1x p1y moveto p2x p2y lineto p2x yMin lineto p1x yMin lineto fill }{ /AA r2 r1 sub c2y div def AA -1 eq {/theta 89.99 def} {/theta AA 1 AA dup mul sub sqrt div 1 atan def} ifelse /SS1 90 theta add dup sin exch cos div def /p1x r1 SS1 SS1 mul SS1 SS1 mul 1 add div sqrt mul neg def /p1y p1x SS1 div neg def /SS2 90 theta sub dup sin exch cos div def /p2x r1 SS2 SS2 mul SS2 SS2 mul 1 add div sqrt mul def /p2y p2x SS2 div neg def r1 r2 gt { /L1maxX p1x yMin p1y sub SS1 div add def /L2maxX p2x yMin p2y sub SS2 div add def }{ /L1maxX 0 def /L2maxX 0 def }ifelse p1x p1y moveto p2x p2y lineto L2maxX L2maxX p2x sub SS2 mul p2y add lineto L1maxX L1maxX p1x sub SS1 mul p1y add lineto fill }ifelse }ifelse }ifelse }if c1x c2x sub dup mul c1y c2y sub dup mul add 0.5 exp 0 dtransform dup mul exch dup mul add 0.5 exp 72 div 0 72 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt 1 index 1 index lt{exch}if pop /hires xdf hires mul /numpix xdf /numsteps NumSamples def /rampIndxInc 1 def /subsampling false def numpix 0 ne { NumSamples numpix div 0.5 gt { /numsteps numpix 2 div round cvi dup 1 le{pop 2}if def /rampIndxInc NumSamples 1 sub numsteps div def /subsampling true def }if }if /xInc c2x c1x sub numsteps div def /yInc c2y c1y sub numsteps div def /rInc r2 r1 sub numsteps div def /cx c1x def /cy c1y def /radius r1 def np xInc 0 eq yInc 0 eq rInc 0 eq and and { 0 getrampcolor cx cy radius 0 360 arc stroke NumSamples 1 sub getrampcolor cx cy radius 72 hires div add 0 360 arc 0 setlinewidth stroke }{ 0 numsteps { dup subsampling{round cvi}if getrampcolor cx cy radius 0 360 arc /cx cx xInc add def /cy cy yInc add def /radius radius rInc add def cx cy radius 360 0 arcn eofill rampIndxInc add }repeat pop }ifelse ext1 { c2y r2 add r1 lt { c2x c2y r2 0 360 arc fill }{ c2y r1 add r2 sub 0.0001 le { c2x c2y r2 360 0 arcn pathbbox /aymax exch def /axmax exch def /aymin exch def /axmin exch def /bxMin xMin axmin min def /byMin yMin aymin min def /bxMax xMax axmax max def /byMax yMax aymax max def bxMin byMin moveto bxMax byMin lineto bxMax byMax lineto bxMin byMax lineto bxMin byMin lineto eofill }{ c2x c2y r2 0 360 arc fill r1 r2 eq { /p1x r2 neg def /p1y c2y def /p2x r2 def /p2y c2y def p1x p1y moveto p2x p2y lineto p2x yMax lineto p1x yMax lineto fill }{ /AA r2 r1 sub c2y div def AA -1 eq {/theta 89.99 def} {/theta AA 1 AA dup mul sub sqrt div 1 atan def} ifelse /SS1 90 theta add dup sin exch cos div def /p1x r2 SS1 SS1 mul SS1 SS1 mul 1 add div sqrt mul neg def /p1y c2y p1x SS1 div sub def /SS2 90 theta sub dup sin exch cos div def /p2x r2 SS2 SS2 mul SS2 SS2 mul 1 add div sqrt mul def /p2y c2y p2x SS2 div sub def r1 r2 lt { /L1maxX p1x yMax p1y sub SS1 div add def /L2maxX p2x yMax p2y sub SS2 div add def }{ /L1maxX 0 def /L2maxX 0 def }ifelse p1x p1y moveto p2x p2y lineto L2maxX L2maxX p2x sub SS2 mul p2y add lineto L1maxX L1maxX p1x sub SS1 mul p1y add lineto fill }ifelse }ifelse }ifelse }if grestore grestore end end end }ifelse }bdf /GenStrips { 40 dict begin /ColorSpaceFamily xdf /background xdf /ext1 xdf /ext0 xdf /BBox xdf /y2 xdf /x2 xdf /y1 xdf /x1 xdf /rampdict xdf /setinkoverprint where{pop/setinkoverprint{pop}def}if gsave BBox length 0 gt { np BBox 0 get BBox 1 get moveto BBox 2 get BBox 0 get sub 0 rlineto 0 BBox 3 get BBox 1 get sub rlineto BBox 2 get BBox 0 get sub neg 0 rlineto closepath clip np }if x1 x2 eq { y1 y2 lt{/theta 90 def}{/theta 270 def}ifelse }{ /slope y2 y1 sub x2 x1 sub div def /theta slope 1 atan def x2 x1 lt y2 y1 ge and{/theta theta 180 sub def}if x2 x1 lt y2 y1 lt and{/theta theta 180 add def}if } ifelse gsave clippath x1 y1 translate theta rotate {pathbbox}stopped {0 0 0 0}if /yMax exch def /xMax exch def /yMin exch def /xMin exch def grestore xMax xMin eq yMax yMin eq or { grestore end }{ rampdict begin 20 dict begin background length 0 gt{background sssetbackground gsave clippath fill grestore}if gsave x1 y1 translate theta rotate /xStart 0 def /xEnd x2 x1 sub dup mul y2 y1 sub dup mul add 0.5 exp def /ySpan yMax yMin sub def /numsteps NumSamples def /rampIndxInc 1 def /subsampling false def xStart 0 transform xEnd 0 transform 3 -1 roll sub dup mul 3 1 roll sub dup mul add 0.5 exp 72 div 0 72 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt 1 index 1 index lt{exch}if pop mul /numpix xdf numpix 0 ne { NumSamples numpix div 0.5 gt { /numsteps numpix 2 div round cvi dup 1 le{pop 2}if def /rampIndxInc NumSamples 1 sub numsteps div def /subsampling true def }if }if ext0 { 0 getrampcolor xMin xStart lt { xMin yMin xMin neg ySpan rectfill }if }if /xInc xEnd xStart sub numsteps div def /x xStart def 0 numsteps { dup subsampling{round cvi}if getrampcolor x yMin xInc ySpan rectfill /x x xInc add def rampIndxInc add }repeat pop ext1{ xMax xEnd gt { xEnd yMin xMax xEnd sub ySpan rectfill }if }if grestore grestore end end end }ifelse }bdf }def /pt { end }def /dt{ }def /pgsv{ //Adobe_AGM_Core/AGMCORE_save save put }def /pgrs{ //Adobe_AGM_Core/AGMCORE_save get restore }def systemdict/findcolorrendering known{ /findcolorrendering systemdict/findcolorrendering get def }if systemdict/setcolorrendering known{ /setcolorrendering systemdict/setcolorrendering get def }if /test_cmyk_color_plate { gsave setcmykcolor currentgray 1 ne grestore }def /inRip_spot_has_ink { dup//Adobe_AGM_Core/AGMCORE_name xddf convert_spot_to_process not }def /map255_to_range { 1 index sub 3 -1 roll 255 div mul add }def /set_csa_crd { /sep_colorspace_dict null AGMCORE_gput begin CSA get_csa_by_name setcolorspace_opt set_crd end } def /map_csa { currentdict/MappedCSA known{MappedCSA null ne}{false}ifelse {pop}{get_csa_by_name/MappedCSA xdf}ifelse }def /setsepcolor { /sep_colorspace_dict AGMCORE_gget begin dup/sep_tint exch AGMCORE_gput TintProc end }def /setdevicencolor { /devicen_colorspace_dict AGMCORE_gget begin Names length copy Names length 1 sub -1 0 { /devicen_tints AGMCORE_gget 3 1 roll xpt }for TintProc end }def /sep_colorspace_proc { /AGMCORE_tmp exch store /sep_colorspace_dict AGMCORE_gget begin currentdict/Components known{ Components aload pop TintMethod/Lab eq{ 2{AGMCORE_tmp mul NComponents 1 roll}repeat LMax sub AGMCORE_tmp mul LMax add NComponents 1 roll }{ TintMethod/Subtractive eq{ NComponents{ AGMCORE_tmp mul NComponents 1 roll }repeat }{ NComponents{ 1 sub AGMCORE_tmp mul 1 add NComponents 1 roll }repeat }ifelse }ifelse }{ ColorLookup AGMCORE_tmp ColorLookup length 1 sub mul round cvi get aload pop }ifelse end }def /sep_colorspace_gray_proc { /AGMCORE_tmp exch store /sep_colorspace_dict AGMCORE_gget begin GrayLookup AGMCORE_tmp GrayLookup length 1 sub mul round cvi get end }def /sep_proc_name { dup 0 get dup/DeviceRGB eq exch/DeviceCMYK eq or level2 not and has_color not and{ pop[/DeviceGray] /sep_colorspace_gray_proc }{ /sep_colorspace_proc }ifelse }def /setsepcolorspace { current_spot_alias{ dup begin Name map_alias{ exch pop }if end }if dup/sep_colorspace_dict exch AGMCORE_gput begin CSA map_csa /AGMCORE_sep_special Name dup()eq exch(All)eq or store AGMCORE_avoid_L2_sep_space{ [/Indexed MappedCSA sep_proc_name 255 exch {255 div}/exec cvx 3 -1 roll[4 1 roll load/exec cvx]cvx ]setcolorspace_opt /TintProc{ 255 mul round cvi setcolor }bdf }{ MappedCSA 0 get/DeviceCMYK eq currentdict/Components known and AGMCORE_sep_special not and{ /TintProc[ Components aload pop Name findcmykcustomcolor /exch cvx/setcustomcolor cvx ]cvx bdf }{ AGMCORE_host_sep Name(All)eq and{ /TintProc{ 1 exch sub setseparationgray }bdf }{ AGMCORE_in_rip_sep MappedCSA 0 get/DeviceCMYK eq and AGMCORE_host_sep or Name()eq and{ /TintProc[ MappedCSA sep_proc_name exch 0 get/DeviceCMYK eq{ cvx/setcmykcolor cvx }{ cvx/setgray cvx }ifelse ]cvx bdf }{ AGMCORE_producing_seps MappedCSA 0 get dup/DeviceCMYK eq exch/DeviceGray eq or and AGMCORE_sep_special not and{ /TintProc[ /dup cvx MappedCSA sep_proc_name cvx exch 0 get/DeviceGray eq{ 1/exch cvx/sub cvx 0 0 0 4 -1/roll cvx }if /Name cvx/findcmykcustomcolor cvx/exch cvx AGMCORE_host_sep{ AGMCORE_is_cmyk_sep /Name cvx /AGMCORE_IsSeparationAProcessColor load/exec cvx /not cvx/and cvx }{ Name inRip_spot_has_ink not }ifelse [ /pop cvx 1 ]cvx/if cvx /setcustomcolor cvx ]cvx bdf }{ /TintProc{setcolor}bdf [/Separation Name MappedCSA sep_proc_name load]setcolorspace_opt }ifelse }ifelse }ifelse }ifelse }ifelse set_crd setsepcolor end }def /additive_blend { 3 dict begin /numarrays xdf /numcolors xdf 0 1 numcolors 1 sub { /c1 xdf 1 0 1 numarrays 1 sub { 1 exch add/index cvx c1/get cvx/mul cvx }for numarrays 1 add 1/roll cvx }for numarrays[/pop cvx]cvx/repeat cvx end }def /subtractive_blend { 3 dict begin /numarrays xdf /numcolors xdf 0 1 numcolors 1 sub { /c1 xdf 1 1 0 1 numarrays 1 sub { 1 3 3 -1 roll add/index cvx c1/get cvx/sub cvx/mul cvx }for /sub cvx numarrays 1 add 1/roll cvx }for numarrays[/pop cvx]cvx/repeat cvx end }def /exec_tint_transform { /TintProc[ /TintTransform cvx/setcolor cvx ]cvx bdf MappedCSA setcolorspace_opt }bdf /devn_makecustomcolor { 2 dict begin /names_index xdf /Names xdf 1 1 1 1 Names names_index get findcmykcustomcolor /devicen_tints AGMCORE_gget names_index get setcustomcolor Names length{pop}repeat end }bdf /setdevicencolorspace { dup/AliasedColorants known{false}{true}ifelse current_spot_alias and{ 7 dict begin /names_index 0 def dup/names_len exch/Names get length def /new_names names_len array def /new_LookupTables names_len array def /alias_cnt 0 def dup/Names get { dup map_alias{ exch pop dup/ColorLookup known{ dup begin new_LookupTables names_index ColorLookup put end }{ dup/Components known{ dup begin new_LookupTables names_index Components put end }{ dup begin new_LookupTables names_index[null null null null]put end }ifelse }ifelse new_names names_index 3 -1 roll/Name get put /alias_cnt alias_cnt 1 add def }{ /name xdf new_names names_index name put dup/LookupTables known{ dup begin new_LookupTables names_index LookupTables names_index get put end }{ dup begin new_LookupTables names_index[null null null null]put end }ifelse }ifelse /names_index names_index 1 add def }forall alias_cnt 0 gt{ /AliasedColorants true def /lut_entry_len new_LookupTables 0 get dup length 256 ge{0 get length}{length}ifelse def 0 1 names_len 1 sub{ /names_index xdf new_LookupTables names_index get dup length 256 ge{0 get length}{length}ifelse lut_entry_len ne{ /AliasedColorants false def exit }{ new_LookupTables names_index get 0 get null eq{ dup/Names get names_index get/name xdf name(Cyan)eq name(Magenta)eq name(Yellow)eq name(Black)eq or or or not{ /AliasedColorants false def exit }if }if }ifelse }for lut_entry_len 1 eq{ /AliasedColorants false def }if AliasedColorants{ dup begin /Names new_names def /LookupTables new_LookupTables def /AliasedColorants true def /NComponents lut_entry_len def /TintMethod NComponents 4 eq{/Subtractive}{/Additive}ifelse def /MappedCSA TintMethod/Additive eq{/DeviceRGB}{/DeviceCMYK}ifelse def currentdict/TTTablesIdx known not{ /TTTablesIdx -1 def }if end }if }if end }if dup/devicen_colorspace_dict exch AGMCORE_gput begin currentdict/AliasedColorants known{ AliasedColorants }{ false }ifelse dup not{ CSA map_csa }if /TintTransform load type/nulltype eq or{ /TintTransform[ 0 1 Names length 1 sub { /TTTablesIdx TTTablesIdx 1 add def dup LookupTables exch get dup 0 get null eq { 1 index Names exch get dup(Cyan)eq { pop exch LookupTables length exch sub /index cvx 0 0 0 } { dup(Magenta)eq { pop exch LookupTables length exch sub /index cvx 0/exch cvx 0 0 }{ (Yellow)eq { exch LookupTables length exch sub /index cvx 0 0 3 -1/roll cvx 0 }{ exch LookupTables length exch sub /index cvx 0 0 0 4 -1/roll cvx }ifelse }ifelse }ifelse 5 -1/roll cvx/astore cvx }{ dup length 1 sub LookupTables length 4 -1 roll sub 1 add /index cvx/mul cvx/round cvx/cvi cvx/get cvx }ifelse Names length TTTablesIdx add 1 add 1/roll cvx }for Names length[/pop cvx]cvx/repeat cvx NComponents Names length TintMethod/Subtractive eq { subtractive_blend }{ additive_blend }ifelse ]cvx bdf }if AGMCORE_host_sep{ Names convert_to_process{ exec_tint_transform } { currentdict/AliasedColorants known{ AliasedColorants not }{ false }ifelse 5 dict begin /AvoidAliasedColorants xdf /painted? false def /names_index 0 def /names_len Names length def AvoidAliasedColorants{ /currentspotalias current_spot_alias def false set_spot_alias }if Names{ AGMCORE_is_cmyk_sep{ dup(Cyan)eq AGMCORE_cyan_plate and exch dup(Magenta)eq AGMCORE_magenta_plate and exch dup(Yellow)eq AGMCORE_yellow_plate and exch (Black)eq AGMCORE_black_plate and or or or{ /devicen_colorspace_dict AGMCORE_gget/TintProc[ Names names_index/devn_makecustomcolor cvx ]cvx ddf /painted? true def }if painted?{exit}if }{ 0 0 0 0 5 -1 roll findcmykcustomcolor 1 setcustomcolor currentgray 0 eq{ /devicen_colorspace_dict AGMCORE_gget/TintProc[ Names names_index/devn_makecustomcolor cvx ]cvx ddf /painted? true def exit }if }ifelse /names_index names_index 1 add def }forall AvoidAliasedColorants{ currentspotalias set_spot_alias }if painted?{ /devicen_colorspace_dict AGMCORE_gget/names_index names_index put }{ /devicen_colorspace_dict AGMCORE_gget/TintProc[ names_len[/pop cvx]cvx/repeat cvx 1/setseparationgray cvx 0 0 0 0/setcmykcolor cvx ]cvx ddf }ifelse end }ifelse } { AGMCORE_in_rip_sep{ Names convert_to_process not }{ level3 }ifelse { [/DeviceN Names MappedCSA/TintTransform load]setcolorspace_opt /TintProc level3 not AGMCORE_in_rip_sep and{ [ Names/length cvx[/pop cvx]cvx/repeat cvx ]cvx bdf }{ {setcolor}bdf }ifelse }{ exec_tint_transform }ifelse }ifelse set_crd /AliasedColorants false def end }def /setindexedcolorspace { dup/indexed_colorspace_dict exch AGMCORE_gput begin currentdict/CSDBase known{ CSDBase/CSD get_res begin currentdict/Names known{ currentdict devncs }{ 1 currentdict sepcs }ifelse AGMCORE_host_sep{ 4 dict begin /compCnt/Names where{pop Names length}{1}ifelse def /NewLookup HiVal 1 add string def 0 1 HiVal{ /tableIndex xdf Lookup dup type/stringtype eq{ compCnt tableIndex map_index }{ exec }ifelse /Names where{ pop setdevicencolor }{ setsepcolor }ifelse currentgray tableIndex exch 255 mul cvi NewLookup 3 1 roll put }for [/Indexed currentcolorspace HiVal NewLookup]setcolorspace_opt end }{ level3 { currentdict/Names known{ [/Indexed[/DeviceN Names MappedCSA/TintTransform load]HiVal Lookup]setcolorspace_opt }{ [/Indexed[/Separation Name MappedCSA sep_proc_name load]HiVal Lookup]setcolorspace_opt }ifelse }{ [/Indexed MappedCSA HiVal [ currentdict/Names known{ Lookup dup type/stringtype eq {/exch cvx CSDBase/CSD get_res/Names get length dup/mul cvx exch/getinterval cvx{255 div}/forall cvx} {/exec cvx}ifelse /TintTransform load/exec cvx }{ Lookup dup type/stringtype eq {/exch cvx/get cvx 255/div cvx} {/exec cvx}ifelse CSDBase/CSD get_res/MappedCSA get sep_proc_name exch pop/load cvx/exec cvx }ifelse ]cvx ]setcolorspace_opt }ifelse }ifelse end set_crd } { CSA map_csa AGMCORE_host_sep level2 not and{ 0 0 0 0 setcmykcolor }{ [/Indexed MappedCSA level2 not has_color not and{ dup 0 get dup/DeviceRGB eq exch/DeviceCMYK eq or{ pop[/DeviceGray] }if HiVal GrayLookup }{ HiVal currentdict/RangeArray known{ { /indexed_colorspace_dict AGMCORE_gget begin Lookup exch dup HiVal gt{ pop HiVal }if NComponents mul NComponents getinterval{}forall NComponents 1 sub -1 0{ RangeArray exch 2 mul 2 getinterval aload pop map255_to_range NComponents 1 roll }for end }bind }{ Lookup }ifelse }ifelse ]setcolorspace_opt set_crd }ifelse }ifelse end }def /setindexedcolor { AGMCORE_host_sep{ /indexed_colorspace_dict AGMCORE_gget begin currentdict/CSDBase known{ CSDBase/CSD get_res begin currentdict/Names known{ map_indexed_devn devn } { Lookup 1 3 -1 roll map_index sep }ifelse end }{ Lookup MappedCSA/DeviceCMYK eq{4}{1}ifelse 3 -1 roll map_index MappedCSA/DeviceCMYK eq{setcmykcolor}{setgray}ifelse }ifelse end }{ level3 not AGMCORE_in_rip_sep and/indexed_colorspace_dict AGMCORE_gget/CSDBase known and{ /indexed_colorspace_dict AGMCORE_gget/CSDBase get/CSD get_res begin map_indexed_devn devn end } { setcolor }ifelse }ifelse }def /ignoreimagedata { currentoverprint not{ gsave dup clonedict begin 1 setgray /Decode[0 1]def /DataSourcedef /MultipleDataSources false def /BitsPerComponent 8 def currentdict end systemdict/image gx grestore }if consumeimagedata }def /add_res { dup/CSD eq{ pop //Adobe_AGM_Core begin /AGMCORE_CSD_cache load 3 1 roll put end }{ defineresource pop }ifelse }def /del_res { { aload pop exch dup/CSD eq{ pop {//Adobe_AGM_Core/AGMCORE_CSD_cache get exch undef}forall }{ exch {1 index undefineresource}forall pop }ifelse }forall }def /get_res { dup/CSD eq{ pop dup type dup/nametype eq exch/stringtype eq or{ AGMCORE_CSD_cache exch get }if }{ findresource }ifelse }def /get_csa_by_name { dup type dup/nametype eq exch/stringtype eq or{ /CSA get_res }if }def /paintproc_buf_init { /count get 0 0 put }def /paintproc_buf_next { dup/count get dup 0 get dup 3 1 roll 1 add 0 xpt get }def /cachepaintproc_compress { 5 dict begin currentfile exch 0 exch/SubFileDecode filter/ReadFilter exch def /ppdict 20 dict def /string_size 16000 def /readbuffer string_size string def currentglobal true setglobal ppdict 1 array dup 0 1 put/count xpt setglobal /LZWFilter { exch dup length 0 eq{ pop }{ ppdict dup length 1 sub 3 -1 roll put }ifelse {string_size}{0}ifelse string }/LZWEncode filter def { ReadFilter readbuffer readstring exch LZWFilter exch writestring not{exit}if }loop LZWFilter closefile ppdict end }def /cachepaintproc { 2 dict begin currentfile exch 0 exch/SubFileDecode filter/ReadFilter exch def /ppdict 20 dict def currentglobal true setglobal ppdict 1 array dup 0 1 put/count xpt setglobal { ReadFilter 16000 string readstring exch ppdict dup length 1 sub 3 -1 roll put not{exit}if }loop ppdict dup dup length 1 sub()put end }def /make_pattern { exch clonedict exch dup matrix currentmatrix matrix concatmatrix 0 0 3 2 roll itransform exch 3 index/XStep get 1 index exch 2 copy div cvi mul sub sub exch 3 index/YStep get 1 index exch 2 copy div cvi mul sub sub matrix translate exch matrix concatmatrix 1 index begin BBox 0 get XStep div cvi XStep mul/xshift exch neg def BBox 1 get YStep div cvi YStep mul/yshift exch neg def BBox 0 get xshift add BBox 1 get yshift add BBox 2 get xshift add BBox 3 get yshift add 4 array astore /BBox exch def [xshift yshift/translate load null/exec load]dup 3/PaintProc load put cvx/PaintProc exch def end gsave 0 setgray makepattern grestore }def /set_pattern { dup/PatternType get 1 eq{ dup/PaintType get 1 eq{ currentoverprint sop[/DeviceGray]setcolorspace 0 setgray }if }if setpattern }def /setcolorspace_opt { dup currentcolorspace eq{pop}{setcolorspace}ifelse }def /updatecolorrendering { currentcolorrendering/RenderingIntent known{ currentcolorrendering/RenderingIntent get } { Intent/AbsoluteColorimetric eq { /absolute_colorimetric_crd AGMCORE_gget dup null eq } { Intent/RelativeColorimetric eq { /relative_colorimetric_crd AGMCORE_gget dup null eq } { Intent/Saturation eq { /saturation_crd AGMCORE_gget dup null eq } { /perceptual_crd AGMCORE_gget dup null eq }ifelse }ifelse }ifelse { pop null } { /RenderingIntent known{null}{Intent}ifelse }ifelse }ifelse Intent ne{ Intent/ColorRendering{findresource}stopped { pop pop systemdict/findcolorrendering known { Intent findcolorrendering { /ColorRendering findresource true exch } { /ColorRendering findresource product(Xerox Phaser 5400)ne exch }ifelse dup Intent/AbsoluteColorimetric eq { /absolute_colorimetric_crd exch AGMCORE_gput } { Intent/RelativeColorimetric eq { /relative_colorimetric_crd exch AGMCORE_gput } { Intent/Saturation eq { /saturation_crd exch AGMCORE_gput } { Intent/Perceptual eq { /perceptual_crd exch AGMCORE_gput } { pop }ifelse }ifelse }ifelse }ifelse 1 index{exch}{pop}ifelse } {false}ifelse } {true}ifelse { dup begin currentdict/TransformPQR known{ currentdict/TransformPQR get aload pop 3{{}eq 3 1 roll}repeat or or } {true}ifelse currentdict/MatrixPQR known{ currentdict/MatrixPQR get aload pop 1.0 eq 9 1 roll 0.0 eq 9 1 roll 0.0 eq 9 1 roll 0.0 eq 9 1 roll 1.0 eq 9 1 roll 0.0 eq 9 1 roll 0.0 eq 9 1 roll 0.0 eq 9 1 roll 1.0 eq and and and and and and and and } {true}ifelse end or { clonedict begin /TransformPQR[ {4 -1 roll 3 get dup 3 1 roll sub 5 -1 roll 3 get 3 -1 roll sub div 3 -1 roll 3 get 3 -1 roll 3 get dup 4 1 roll sub mul add}bind {4 -1 roll 4 get dup 3 1 roll sub 5 -1 roll 4 get 3 -1 roll sub div 3 -1 roll 4 get 3 -1 roll 4 get dup 4 1 roll sub mul add}bind {4 -1 roll 5 get dup 3 1 roll sub 5 -1 roll 5 get 3 -1 roll sub div 3 -1 roll 5 get 3 -1 roll 5 get dup 4 1 roll sub mul add}bind ]def /MatrixPQR[0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296]def /RangePQR[-0.3227950745 2.3229645538 -1.5003771057 3.5003465881 -0.1369979095 2.136967392]def currentdict end }if setcolorrendering_opt }if }if }def /set_crd { AGMCORE_host_sep not level2 and{ currentdict/ColorRendering known{ ColorRendering/ColorRendering{findresource}stopped not{setcolorrendering_opt}if }{ currentdict/Intent known{ updatecolorrendering }if }ifelse currentcolorspace dup type/arraytype eq {0 get}if /DeviceRGB eq { currentdict/UCR known {/UCR}{/AGMCORE_currentucr}ifelse load setundercolorremoval currentdict/BG known {/BG}{/AGMCORE_currentbg}ifelse load setblackgeneration }if }if }def /set_ucrbg { dup null eq{pop/AGMCORE_currentbg load}{/Procedure get_res}ifelse setblackgeneration dup null eq{pop/AGMCORE_currentucr load}{/Procedure get_res}ifelse setundercolorremoval }def /setcolorrendering_opt { dup currentcolorrendering eq{ pop }{ clonedict begin /Intent Intent def currentdict end setcolorrendering }ifelse }def /cpaint_gcomp { convert_to_process//Adobe_AGM_Core/AGMCORE_ConvertToProcess xddf //Adobe_AGM_Core/AGMCORE_ConvertToProcess get not { (%end_cpaint_gcomp)flushinput }if }def /cpaint_gsep { //Adobe_AGM_Core/AGMCORE_ConvertToProcess get { (%end_cpaint_gsep)flushinput }if }def /cpaint_gend {np}def /T1_path { currentfile token pop currentfile token pop mo { currentfile token pop dup type/stringtype eq {pop exit}if 0 exch rlineto currentfile token pop dup type/stringtype eq {pop exit}if 0 rlineto }loop }def /T1_gsave level3 {/clipsave} {/gsave}ifelse load def /T1_grestore level3 {/cliprestore} {/grestore}ifelse load def /set_spot_alias_ary { dup inherit_aliases //Adobe_AGM_Core/AGMCORE_SpotAliasAry xddf }def /set_spot_normalization_ary { dup inherit_aliases dup length /AGMCORE_SpotAliasAry where{pop AGMCORE_SpotAliasAry length add}if array //Adobe_AGM_Core/AGMCORE_SpotAliasAry2 xddf /AGMCORE_SpotAliasAry where{ pop AGMCORE_SpotAliasAry2 0 AGMCORE_SpotAliasAry putinterval AGMCORE_SpotAliasAry length }{0}ifelse AGMCORE_SpotAliasAry2 3 1 roll exch putinterval true set_spot_alias }def /inherit_aliases { {dup/Name get map_alias{/CSD put}{pop}ifelse}forall }def /set_spot_alias { /AGMCORE_SpotAliasAry2 where{ /AGMCORE_current_spot_alias 3 -1 roll put }{ pop }ifelse }def /current_spot_alias { /AGMCORE_SpotAliasAry2 where{ /AGMCORE_current_spot_alias get }{ false }ifelse }def /map_alias { /AGMCORE_SpotAliasAry2 where{ begin /AGMCORE_name xdf false AGMCORE_SpotAliasAry2{ dup/Name get AGMCORE_name eq{ /CSD get/CSD get_res exch pop true exit }{ pop }ifelse }forall end }{ pop false }ifelse }bdf /spot_alias { true set_spot_alias /AGMCORE_&setcustomcolor AGMCORE_key_known not{ //Adobe_AGM_Core/AGMCORE_&setcustomcolor/setcustomcolor load put }if /customcolor_tint 1 AGMCORE_gput //Adobe_AGM_Core begin /setcustomcolor { //Adobe_AGM_Core begin dup/customcolor_tint exch AGMCORE_gput 1 index aload pop pop 1 eq exch 1 eq and exch 1 eq and exch 1 eq and not current_spot_alias and{1 index 4 get map_alias}{false}ifelse { false set_spot_alias /sep_colorspace_dict AGMCORE_gget null ne 3 1 roll 2 index{ exch pop/sep_tint AGMCORE_gget exch }if mark 3 1 roll setsepcolorspace counttomark 0 ne{ setsepcolor }if pop not{/sep_tint 1.0 AGMCORE_gput}if pop true set_spot_alias }{ AGMCORE_&setcustomcolor }ifelse end }bdf end }def /begin_feature { Adobe_AGM_Core/AGMCORE_feature_dictCount countdictstack put count Adobe_AGM_Core/AGMCORE_feature_opCount 3 -1 roll put {Adobe_AGM_Core/AGMCORE_feature_ctm matrix currentmatrix put}if }def /end_feature { 2 dict begin /spd/setpagedevice load def /setpagedevice{get_gstate spd set_gstate}def stopped{$error/newerror false put}if end count Adobe_AGM_Core/AGMCORE_feature_opCount get sub dup 0 gt{{pop}repeat}{pop}ifelse countdictstack Adobe_AGM_Core/AGMCORE_feature_dictCount get sub dup 0 gt{{end}repeat}{pop}ifelse {Adobe_AGM_Core/AGMCORE_feature_ctm get setmatrix}if }def /set_negative { //Adobe_AGM_Core begin /AGMCORE_inverting exch def level2{ currentpagedevice/NegativePrint known AGMCORE_distilling not and{ currentpagedevice/NegativePrint get//Adobe_AGM_Core/AGMCORE_inverting get ne{ true begin_feature true{ <>setpagedevice }end_feature }if /AGMCORE_inverting false def }if }if AGMCORE_inverting{ [{1 exch sub}/exec load dup currenttransfer exch]cvx bind settransfer AGMCORE_distilling{ erasepage }{ gsave np clippath 1/setseparationgray where{pop setseparationgray}{setgray}ifelse /AGMIRS_&fill where{pop AGMIRS_&fill}{fill}ifelse grestore }ifelse }if end }def /lw_save_restore_override{ /md where{ pop md begin initializepage /initializepage{}def /pmSVsetup{}def /endp{}def /pse{}def /psb{}def /orig_showpage where {pop} {/orig_showpage/showpage load def} ifelse /showpage{orig_showpage gR}def end }if }def /pscript_showpage_override{ /NTPSOct95 where { begin showpage save /showpage/restore load def /restore{exch pop}def end }if }def /driver_media_override { /md where{ pop md/initializepage known{ md/initializepage{}put }if md/rC known{ md/rC{4{pop}repeat}put }if }if /mysetup where{ /mysetup[1 0 0 1 0 0]put }if Adobe_AGM_Core/AGMCORE_Default_CTM matrix currentmatrix put level2 {Adobe_AGM_Core/AGMCORE_Default_PageSize currentpagedevice/PageSize get put}if }def /driver_check_media_override { /PrepsDict where {pop} { Adobe_AGM_Core/AGMCORE_Default_CTM get matrix currentmatrix ne Adobe_AGM_Core/AGMCORE_Default_PageSize get type/arraytype eq { Adobe_AGM_Core/AGMCORE_Default_PageSize get 0 get currentpagedevice/PageSize get 0 get eq and Adobe_AGM_Core/AGMCORE_Default_PageSize get 1 get currentpagedevice/PageSize get 1 get eq and }if { Adobe_AGM_Core/AGMCORE_Default_CTM get setmatrix }if }ifelse }def AGMCORE_err_strings begin /AGMCORE_bad_environ(Environment not satisfactory for this job. Ensure that the PPD is correct or that the PostScript level requested is supported by this printer. )def /AGMCORE_color_space_onhost_seps(This job contains colors that will not separate with on-host methods. )def /AGMCORE_invalid_color_space(This job contains an invalid color space. )def end /set_def_ht {AGMCORE_def_ht sethalftone}def /set_def_flat {AGMCORE_Default_flatness setflat}def end systemdict/setpacking known {setpacking}if %%EndResource %%BeginResource: procset Adobe_CoolType_Core 2.31 0 %%Copyright: Copyright 1997-2006 Adobe Systems Incorporated. All Rights Reserved. %%Version: 2.31 0 10 dict begin /Adobe_CoolType_Passthru currentdict def /Adobe_CoolType_Core_Defined userdict/Adobe_CoolType_Core known def Adobe_CoolType_Core_Defined {/Adobe_CoolType_Core userdict/Adobe_CoolType_Core get def} if userdict/Adobe_CoolType_Core 70 dict dup begin put /Adobe_CoolType_Version 2.31 def /Level2? systemdict/languagelevel known dup {pop systemdict/languagelevel get 2 ge} if def Level2? not { /currentglobal false def /setglobal/pop load def /gcheck{pop false}bind def /currentpacking false def /setpacking/pop load def /SharedFontDirectory 0 dict def } if currentpacking true setpacking currentglobal false setglobal userdict/Adobe_CoolType_Data 2 copy known not {2 copy 10 dict put} if get begin /@opStackCountByLevel 32 dict def /@opStackLevel 0 def /@dictStackCountByLevel 32 dict def /@dictStackLevel 0 def end setglobal currentglobal true setglobal userdict/Adobe_CoolType_GVMFonts known not {userdict/Adobe_CoolType_GVMFonts 10 dict put} if setglobal currentglobal false setglobal userdict/Adobe_CoolType_LVMFonts known not {userdict/Adobe_CoolType_LVMFonts 10 dict put} if setglobal /ct_VMDictPut { dup gcheck{Adobe_CoolType_GVMFonts}{Adobe_CoolType_LVMFonts}ifelse 3 1 roll put }bind def /ct_VMDictUndef { dup Adobe_CoolType_GVMFonts exch known {Adobe_CoolType_GVMFonts exch undef} { dup Adobe_CoolType_LVMFonts exch known {Adobe_CoolType_LVMFonts exch undef} {pop} ifelse }ifelse }bind def /ct_str1 1 string def /ct_xshow { /_ct_na exch def /_ct_i 0 def currentpoint /_ct_y exch def /_ct_x exch def { pop pop ct_str1 exch 0 exch put ct_str1 show {_ct_na _ct_i get}stopped {pop pop} { _ct_x _ct_y moveto 0 rmoveto } ifelse /_ct_i _ct_i 1 add def currentpoint /_ct_y exch def /_ct_x exch def } exch @cshow }bind def /ct_yshow { /_ct_na exch def /_ct_i 0 def currentpoint /_ct_y exch def /_ct_x exch def { pop pop ct_str1 exch 0 exch put ct_str1 show {_ct_na _ct_i get}stopped {pop pop} { _ct_x _ct_y moveto 0 exch rmoveto } ifelse /_ct_i _ct_i 1 add def currentpoint /_ct_y exch def /_ct_x exch def } exch @cshow }bind def /ct_xyshow { /_ct_na exch def /_ct_i 0 def currentpoint /_ct_y exch def /_ct_x exch def { pop pop ct_str1 exch 0 exch put ct_str1 show {_ct_na _ct_i get}stopped {pop pop} { {_ct_na _ct_i 1 add get}stopped {pop pop pop} { _ct_x _ct_y moveto rmoveto } ifelse } ifelse /_ct_i _ct_i 2 add def currentpoint /_ct_y exch def /_ct_x exch def } exch @cshow }bind def /xsh{{@xshow}stopped{Adobe_CoolType_Data begin ct_xshow end}if}bind def /ysh{{@yshow}stopped{Adobe_CoolType_Data begin ct_yshow end}if}bind def /xysh{{@xyshow}stopped{Adobe_CoolType_Data begin ct_xyshow end}if}bind def currentglobal true setglobal /ct_T3Defs { /BuildChar { 1 index/Encoding get exch get 1 index/BuildGlyph get exec }bind def /BuildGlyph { exch begin GlyphProcs exch get exec end }bind def }bind def setglobal /@_SaveStackLevels { Adobe_CoolType_Data begin /@vmState currentglobal def false setglobal @opStackCountByLevel @opStackLevel 2 copy known not { 2 copy 3 dict dup/args 7 index 5 add array put put get } { get dup/args get dup length 3 index lt { dup length 5 add array exch 1 index exch 0 exch putinterval 1 index exch/args exch put } {pop} ifelse } ifelse begin count 1 sub 1 index lt {pop count} if dup/argCount exch def dup 0 gt { args exch 0 exch getinterval astore pop } {pop} ifelse count /restCount exch def end /@opStackLevel @opStackLevel 1 add def countdictstack 1 sub @dictStackCountByLevel exch @dictStackLevel exch put /@dictStackLevel @dictStackLevel 1 add def @vmState setglobal end }bind def /@_RestoreStackLevels { Adobe_CoolType_Data begin /@opStackLevel @opStackLevel 1 sub def @opStackCountByLevel @opStackLevel get begin count restCount sub dup 0 gt {{pop}repeat} {pop} ifelse args 0 argCount getinterval{}forall end /@dictStackLevel @dictStackLevel 1 sub def @dictStackCountByLevel @dictStackLevel get end countdictstack exch sub dup 0 gt {{end}repeat} {pop} ifelse }bind def /@_PopStackLevels { Adobe_CoolType_Data begin /@opStackLevel @opStackLevel 1 sub def /@dictStackLevel @dictStackLevel 1 sub def end }bind def /@Raise { exch cvx exch errordict exch get exec stop }bind def /@ReRaise { cvx $error/errorname get errordict exch get exec stop }bind def /@Stopped { 0 @#Stopped }bind def /@#Stopped { @_SaveStackLevels stopped {@_RestoreStackLevels true} {@_PopStackLevels false} ifelse }bind def /@Arg { Adobe_CoolType_Data begin @opStackCountByLevel @opStackLevel 1 sub get begin args exch argCount 1 sub exch sub get end end }bind def currentglobal true setglobal /CTHasResourceForAllBug Level2? { 1 dict dup /@shouldNotDisappearDictValue true def Adobe_CoolType_Data exch/@shouldNotDisappearDict exch put begin count @_SaveStackLevels {(*){pop stop}128 string/Category resourceforall} stopped pop @_RestoreStackLevels currentdict Adobe_CoolType_Data/@shouldNotDisappearDict get dup 3 1 roll ne dup 3 1 roll { /@shouldNotDisappearDictValue known { { end currentdict 1 index eq {pop exit} if } loop } if } { pop end } ifelse } {false} ifelse def true setglobal /CTHasResourceStatusBug Level2? { mark {/steveamerige/Category resourcestatus} stopped {cleartomark true} {cleartomark currentglobal not} ifelse } {false} ifelse def setglobal /CTResourceStatus { mark 3 1 roll /Category findresource begin ({ResourceStatus}stopped)0()/SubFileDecode filter cvx exec {cleartomark false} {{3 2 roll pop true}{cleartomark false}ifelse} ifelse end }bind def /CTWorkAroundBugs { Level2? { /cid_PreLoad/ProcSet resourcestatus { pop pop currentglobal mark { (*) { dup/CMap CTHasResourceStatusBug {CTResourceStatus} {resourcestatus} ifelse { pop dup 0 eq exch 1 eq or { dup/CMap findresource gcheck setglobal /CMap undefineresource } { pop CTHasResourceForAllBug {exit} {stop} ifelse } ifelse } {pop} ifelse } 128 string/CMap resourceforall } stopped {cleartomark} stopped pop setglobal } if } if }bind def /ds { Adobe_CoolType_Core begin CTWorkAroundBugs /mo/moveto load def /nf/newencodedfont load def /msf{makefont setfont}bind def /uf{dup undefinefont ct_VMDictUndef}bind def /ur/undefineresource load def /chp/charpath load def /awsh/awidthshow load def /wsh/widthshow load def /ash/ashow load def /@xshow/xshow load def /@yshow/yshow load def /@xyshow/xyshow load def /@cshow/cshow load def /sh/show load def /rp/repeat load def /.n/.notdef def end currentglobal false setglobal userdict/Adobe_CoolType_Data 2 copy known not {2 copy 10 dict put} if get begin /AddWidths? false def /CC 0 def /charcode 2 string def /@opStackCountByLevel 32 dict def /@opStackLevel 0 def /@dictStackCountByLevel 32 dict def /@dictStackLevel 0 def /InVMFontsByCMap 10 dict def /InVMDeepCopiedFonts 10 dict def end setglobal }bind def /dt { currentdict Adobe_CoolType_Core eq {end} if }bind def /ps { Adobe_CoolType_Core begin Adobe_CoolType_GVMFonts begin Adobe_CoolType_LVMFonts begin SharedFontDirectory begin }bind def /pt { end end end end }bind def /unload { systemdict/languagelevel known { systemdict/languagelevel get 2 ge { userdict/Adobe_CoolType_Core 2 copy known {undef} {pop pop} ifelse } if } if }bind def /ndf { 1 index where {pop pop pop} {dup xcheck{bind}if def} ifelse }def /findfont systemdict begin userdict begin /globaldict where{/globaldict get begin}if dup where pop exch get /globaldict where{pop end}if end end Adobe_CoolType_Core_Defined {/systemfindfont exch def} { /findfont 1 index def /systemfindfont exch def } ifelse /undefinefont {pop}ndf /copyfont { currentglobal 3 1 roll 1 index gcheck setglobal dup null eq{0}{dup length}ifelse 2 index length add 1 add dict begin exch { 1 index/FID eq {pop pop} {def} ifelse } forall dup null eq {pop} {{def}forall} ifelse currentdict end exch setglobal }bind def /copyarray { currentglobal exch dup gcheck setglobal dup length array copy exch setglobal }bind def /newencodedfont { currentglobal { SharedFontDirectory 3 index known {SharedFontDirectory 3 index get/FontReferenced known} {false} ifelse } { FontDirectory 3 index known {FontDirectory 3 index get/FontReferenced known} { SharedFontDirectory 3 index known {SharedFontDirectory 3 index get/FontReferenced known} {false} ifelse } ifelse } ifelse dup { 3 index findfont/FontReferenced get 2 index dup type/nametype eq {findfont} if ne {pop false} if } if dup { 1 index dup type/nametype eq {findfont} if dup/CharStrings known { /CharStrings get length 4 index findfont/CharStrings get length ne { pop false } if } {pop} ifelse } if { pop 1 index findfont /Encoding get exch 0 1 255 {2 copy get 3 index 3 1 roll put} for pop pop pop } { currentglobal 4 1 roll dup type/nametype eq {findfont} if dup gcheck setglobal dup dup maxlength 2 add dict begin exch { 1 index/FID ne 2 index/Encoding ne and {def} {pop pop} ifelse } forall /FontReferenced exch def /Encoding exch dup length array copy def /FontName 1 index dup type/stringtype eq{cvn}if def dup currentdict end definefont ct_VMDictPut setglobal } ifelse }bind def /SetSubstituteStrategy { $SubstituteFont begin dup type/dicttype ne {0 dict} if currentdict/$Strategies known { exch $Strategies exch 2 copy known { get 2 copy maxlength exch maxlength add dict begin {def}forall {def}forall currentdict dup/$Init known {dup/$Init get exec} if end /$Strategy exch def } {pop pop pop} ifelse } {pop pop} ifelse end }bind def /scff { $SubstituteFont begin dup type/stringtype eq {dup length exch} {null} ifelse /$sname exch def /$slen exch def /$inVMIndex $sname null eq { 1 index $str cvs dup length $slen sub $slen getinterval cvn } {$sname} ifelse def end {findfont} @Stopped { dup length 8 add string exch 1 index 0(BadFont:)putinterval 1 index exch 8 exch dup length string cvs putinterval cvn {findfont} @Stopped {pop/Courier findfont} if } if $SubstituteFont begin /$sname null def /$slen 0 def /$inVMIndex null def end }bind def /isWidthsOnlyFont { dup/WidthsOnly known {pop pop true} { dup/FDepVector known {/FDepVector get{isWidthsOnlyFont dup{exit}if}forall} { dup/FDArray known {/FDArray get{isWidthsOnlyFont dup{exit}if}forall} {pop} ifelse } ifelse } ifelse }bind def /ct_StyleDicts 4 dict dup begin /Adobe-Japan1 4 dict dup begin Level2? { /Serif /HeiseiMin-W3-83pv-RKSJ-H/Font resourcestatus {pop pop/HeiseiMin-W3} { /CIDFont/Category resourcestatus { pop pop /HeiseiMin-W3/CIDFont resourcestatus {pop pop/HeiseiMin-W3} {/Ryumin-Light} ifelse } {/Ryumin-Light} ifelse } ifelse def /SansSerif /HeiseiKakuGo-W5-83pv-RKSJ-H/Font resourcestatus {pop pop/HeiseiKakuGo-W5} { /CIDFont/Category resourcestatus { pop pop /HeiseiKakuGo-W5/CIDFont resourcestatus {pop pop/HeiseiKakuGo-W5} {/GothicBBB-Medium} ifelse } {/GothicBBB-Medium} ifelse } ifelse def /HeiseiMaruGo-W4-83pv-RKSJ-H/Font resourcestatus {pop pop/HeiseiMaruGo-W4} { /CIDFont/Category resourcestatus { pop pop /HeiseiMaruGo-W4/CIDFont resourcestatus {pop pop/HeiseiMaruGo-W4} { /Jun101-Light-RKSJ-H/Font resourcestatus {pop pop/Jun101-Light} {SansSerif} ifelse } ifelse } { /Jun101-Light-RKSJ-H/Font resourcestatus {pop pop/Jun101-Light} {SansSerif} ifelse } ifelse } ifelse /RoundSansSerif exch def /Default Serif def } { /Serif/Ryumin-Light def /SansSerif/GothicBBB-Medium def { (fonts/Jun101-Light-83pv-RKSJ-H)status }stopped {pop}{ {pop pop pop pop/Jun101-Light} {SansSerif} ifelse /RoundSansSerif exch def }ifelse /Default Serif def } ifelse end def /Adobe-Korea1 4 dict dup begin /Serif/HYSMyeongJo-Medium def /SansSerif/HYGoThic-Medium def /RoundSansSerif SansSerif def /Default Serif def end def /Adobe-GB1 4 dict dup begin /Serif/STSong-Light def /SansSerif/STHeiti-Regular def /RoundSansSerif SansSerif def /Default Serif def end def /Adobe-CNS1 4 dict dup begin /Serif/MKai-Medium def /SansSerif/MHei-Medium def /RoundSansSerif SansSerif def /Default Serif def end def end def Level2?{currentglobal true setglobal}if /ct_BoldRomanWidthProc { stringwidth 1 index 0 ne{exch .03 add exch}if setcharwidth 0 0 }bind def /ct_Type0WidthProc { dup stringwidth 0 0 moveto 2 index true charpath pathbbox 0 -1 7 index 2 div .88 setcachedevice2 pop 0 0 }bind def /ct_Type0WMode1WidthProc { dup stringwidth pop 2 div neg -0.88 2 copy moveto 0 -1 5 -1 roll true charpath pathbbox setcachedevice }bind def /cHexEncoding [/c00/c01/c02/c03/c04/c05/c06/c07/c08/c09/c0A/c0B/c0C/c0D/c0E/c0F/c10/c11/c12 /c13/c14/c15/c16/c17/c18/c19/c1A/c1B/c1C/c1D/c1E/c1F/c20/c21/c22/c23/c24/c25 /c26/c27/c28/c29/c2A/c2B/c2C/c2D/c2E/c2F/c30/c31/c32/c33/c34/c35/c36/c37/c38 /c39/c3A/c3B/c3C/c3D/c3E/c3F/c40/c41/c42/c43/c44/c45/c46/c47/c48/c49/c4A/c4B /c4C/c4D/c4E/c4F/c50/c51/c52/c53/c54/c55/c56/c57/c58/c59/c5A/c5B/c5C/c5D/c5E /c5F/c60/c61/c62/c63/c64/c65/c66/c67/c68/c69/c6A/c6B/c6C/c6D/c6E/c6F/c70/c71 /c72/c73/c74/c75/c76/c77/c78/c79/c7A/c7B/c7C/c7D/c7E/c7F/c80/c81/c82/c83/c84 /c85/c86/c87/c88/c89/c8A/c8B/c8C/c8D/c8E/c8F/c90/c91/c92/c93/c94/c95/c96/c97 /c98/c99/c9A/c9B/c9C/c9D/c9E/c9F/cA0/cA1/cA2/cA3/cA4/cA5/cA6/cA7/cA8/cA9/cAA /cAB/cAC/cAD/cAE/cAF/cB0/cB1/cB2/cB3/cB4/cB5/cB6/cB7/cB8/cB9/cBA/cBB/cBC/cBD /cBE/cBF/cC0/cC1/cC2/cC3/cC4/cC5/cC6/cC7/cC8/cC9/cCA/cCB/cCC/cCD/cCE/cCF/cD0 /cD1/cD2/cD3/cD4/cD5/cD6/cD7/cD8/cD9/cDA/cDB/cDC/cDD/cDE/cDF/cE0/cE1/cE2/cE3 /cE4/cE5/cE6/cE7/cE8/cE9/cEA/cEB/cEC/cED/cEE/cEF/cF0/cF1/cF2/cF3/cF4/cF5/cF6 /cF7/cF8/cF9/cFA/cFB/cFC/cFD/cFE/cFF]def /ct_BoldBaseFont 11 dict begin /FontType 3 def /FontMatrix[1 0 0 1 0 0]def /FontBBox[0 0 1 1]def /Encoding cHexEncoding def /_setwidthProc/ct_BoldRomanWidthProc load def /_bcstr1 1 string def /BuildChar { exch begin _basefont setfont _bcstr1 dup 0 4 -1 roll put dup _setwidthProc 3 copy moveto show _basefonto setfont moveto show end }bind def currentdict end def systemdict/composefont known { /ct_DefineIdentity-H { /Identity-H/CMap resourcestatus { pop pop } { /CIDInit/ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo 3 dict dup begin /Registry(Adobe)def /Ordering(Identity)def /Supplement 0 def end def /CMapName/Identity-H def /CMapVersion 1.000 def /CMapType 1 def 1 begincodespacerange <0000> endcodespacerange 1 begincidrange <0000>0 endcidrange endcmap CMapName currentdict/CMap defineresource pop end end } ifelse } def /ct_BoldBaseCIDFont 11 dict begin /CIDFontType 1 def /CIDFontName/ct_BoldBaseCIDFont def /FontMatrix[1 0 0 1 0 0]def /FontBBox[0 0 1 1]def /_setwidthProc/ct_Type0WidthProc load def /_bcstr2 2 string def /BuildGlyph { exch begin _basefont setfont _bcstr2 1 2 index 256 mod put _bcstr2 0 3 -1 roll 256 idiv put _bcstr2 dup _setwidthProc 3 copy moveto show _basefonto setfont moveto show end }bind def currentdict end def }if Level2?{setglobal}if /ct_CopyFont{ { 1 index/FID ne 2 index/UniqueID ne and {def}{pop pop}ifelse }forall }bind def /ct_Type0CopyFont { exch dup length dict begin ct_CopyFont [ exch FDepVector { dup/FontType get 0 eq { 1 index ct_Type0CopyFont /_ctType0 exch definefont } { /_ctBaseFont exch 2 index exec } ifelse exch } forall pop ] /FDepVector exch def currentdict end }bind def /ct_MakeBoldFont { dup/ct_SyntheticBold known { dup length 3 add dict begin ct_CopyFont /ct_StrokeWidth .03 0 FontMatrix idtransform pop def /ct_SyntheticBold true def currentdict end definefont } { dup dup length 3 add dict begin ct_CopyFont /PaintType 2 def /StrokeWidth .03 0 FontMatrix idtransform pop def /dummybold currentdict end definefont dup/FontType get dup 9 ge exch 11 le and { ct_BoldBaseCIDFont dup length 3 add dict copy begin dup/CIDSystemInfo get/CIDSystemInfo exch def ct_DefineIdentity-H /_Type0Identity/Identity-H 3 -1 roll[exch]composefont /_basefont exch def /_Type0Identity/Identity-H 3 -1 roll[exch]composefont /_basefonto exch def currentdict end /CIDFont defineresource } { ct_BoldBaseFont dup length 3 add dict copy begin /_basefont exch def /_basefonto exch def currentdict end definefont } ifelse } ifelse }bind def /ct_MakeBold{ 1 index 1 index findfont currentglobal 5 1 roll dup gcheck setglobal dup /FontType get 0 eq { dup/WMode known{dup/WMode get 1 eq}{false}ifelse version length 4 ge and {version 0 4 getinterval cvi 2015 ge} {true} ifelse {/ct_Type0WidthProc} {/ct_Type0WMode1WidthProc} ifelse ct_BoldBaseFont/_setwidthProc 3 -1 roll load put {ct_MakeBoldFont}ct_Type0CopyFont definefont } { dup/_fauxfont known not 1 index/SubstMaster known not and { ct_BoldBaseFont/_setwidthProc /ct_BoldRomanWidthProc load put ct_MakeBoldFont } { 2 index 2 index eq {exch pop } { dup length dict begin ct_CopyFont currentdict end definefont } ifelse } ifelse } ifelse pop pop pop setglobal }bind def /?str1 256 string def /?set { $SubstituteFont begin /$substituteFound false def /$fontname 1 index def /$doSmartSub false def end dup findfont $SubstituteFont begin $substituteFound {false} { dup/FontName known { dup/FontName get $fontname eq 1 index/DistillerFauxFont known not and /currentdistillerparams where {pop false 2 index isWidthsOnlyFont not and} if } {false} ifelse } ifelse exch pop /$doSmartSub true def end { 5 1 roll pop pop pop pop findfont } { 1 index findfont dup/FontType get 3 eq { 6 1 roll pop pop pop pop pop false } {pop true} ifelse { $SubstituteFont begin pop pop /$styleArray 1 index def /$regOrdering 2 index def pop pop 0 1 $styleArray length 1 sub { $styleArray exch get ct_StyleDicts $regOrdering 2 copy known { get exch 2 copy known not {pop/Default} if get dup type/nametype eq { ?str1 cvs length dup 1 add exch ?str1 exch(-)putinterval exch dup length exch ?str1 exch 3 index exch putinterval add ?str1 exch 0 exch getinterval cvn } { pop pop/Unknown } ifelse } { pop pop pop pop/Unknown } ifelse } for end findfont }if } ifelse currentglobal false setglobal 3 1 roll null copyfont definefont pop setglobal }bind def setpacking userdict/$SubstituteFont 25 dict put 1 dict begin /SubstituteFont dup $error exch 2 copy known {get} {pop pop{pop/Courier}bind} ifelse def /currentdistillerparams where dup { pop pop currentdistillerparams/CannotEmbedFontPolicy 2 copy known {get/Error eq} {pop pop false} ifelse } if not { countdictstack array dictstack 0 get begin userdict begin $SubstituteFont begin /$str 128 string def /$fontpat 128 string def /$slen 0 def /$sname null def /$match false def /$fontname null def /$substituteFound false def /$inVMIndex null def /$doSmartSub true def /$depth 0 def /$fontname null def /$italicangle 26.5 def /$dstack null def /$Strategies 10 dict dup begin /$Type3Underprint { currentglobal exch false setglobal 11 dict begin /UseFont exch $WMode 0 ne { dup length dict copy dup/WMode $WMode put /UseFont exch definefont } if def /FontName $fontname dup type/stringtype eq{cvn}if def /FontType 3 def /FontMatrix[.001 0 0 .001 0 0]def /Encoding 256 array dup 0 1 255{/.notdef put dup}for pop def /FontBBox[0 0 0 0]def /CCInfo 7 dict dup begin /cc null def /x 0 def /y 0 def end def /BuildChar { exch begin CCInfo begin 1 string dup 0 3 index put exch pop /cc exch def UseFont 1000 scalefont setfont cc stringwidth/y exch def/x exch def x y setcharwidth $SubstituteFont/$Strategy get/$Underprint get exec 0 0 moveto cc show x y moveto end end }bind def currentdict end exch setglobal }bind def /$GetaTint 2 dict dup begin /$BuildFont { dup/WMode known {dup/WMode get} {0} ifelse /$WMode exch def $fontname exch dup/FontName known { dup/FontName get dup type/stringtype eq{cvn}if } {/unnamedfont} ifelse exch Adobe_CoolType_Data/InVMDeepCopiedFonts get 1 index/FontName get known { pop Adobe_CoolType_Data/InVMDeepCopiedFonts get 1 index get null copyfont } {$deepcopyfont} ifelse exch 1 index exch/FontBasedOn exch put dup/FontName $fontname dup type/stringtype eq{cvn}if put definefont Adobe_CoolType_Data/InVMDeepCopiedFonts get begin dup/FontBasedOn get 1 index def end }bind def /$Underprint { gsave x abs y abs gt {/y 1000 def} {/x -1000 def 500 120 translate} ifelse Level2? { [/Separation(All)/DeviceCMYK{0 0 0 1 pop}] setcolorspace } {0 setgray} ifelse 10 setlinewidth x .8 mul [7 3] { y mul 8 div 120 sub x 10 div exch moveto 0 y 4 div neg rlineto dup 0 rlineto 0 y 4 div rlineto closepath gsave Level2? {.2 setcolor} {.8 setgray} ifelse fill grestore stroke } forall pop grestore }bind def end def /$Oblique 1 dict dup begin /$BuildFont { currentglobal exch dup gcheck setglobal null copyfont begin /FontBasedOn currentdict/FontName known { FontName dup type/stringtype eq{cvn}if } {/unnamedfont} ifelse def /FontName $fontname dup type/stringtype eq{cvn}if def /currentdistillerparams where {pop} { /FontInfo currentdict/FontInfo known {FontInfo null copyfont} {2 dict} ifelse dup begin /ItalicAngle $italicangle def /FontMatrix FontMatrix [1 0 ItalicAngle dup sin exch cos div 1 0 0] matrix concatmatrix readonly end 4 2 roll def def } ifelse FontName currentdict end definefont exch setglobal }bind def end def /$None 1 dict dup begin /$BuildFont{}bind def end def end def /$Oblique SetSubstituteStrategy /$findfontByEnum { dup type/stringtype eq{cvn}if dup/$fontname exch def $sname null eq {$str cvs dup length $slen sub $slen getinterval} {pop $sname} ifelse $fontpat dup 0(fonts/*)putinterval exch 7 exch putinterval /$match false def $SubstituteFont/$dstack countdictstack array dictstack put mark { $fontpat 0 $slen 7 add getinterval {/$match exch def exit} $str filenameforall } stopped { cleardictstack currentdict true $SubstituteFont/$dstack get { exch { 1 index eq {pop false} {true} ifelse } {begin false} ifelse } forall pop } if cleartomark /$slen 0 def $match false ne {$match(fonts/)anchorsearch pop pop cvn} {/Courier} ifelse }bind def /$ROS 1 dict dup begin /Adobe 4 dict dup begin /Japan1 [/Ryumin-Light/HeiseiMin-W3 /GothicBBB-Medium/HeiseiKakuGo-W5 /HeiseiMaruGo-W4/Jun101-Light]def /Korea1 [/HYSMyeongJo-Medium/HYGoThic-Medium]def /GB1 [/STSong-Light/STHeiti-Regular]def /CNS1 [/MKai-Medium/MHei-Medium]def end def end def /$cmapname null def /$deepcopyfont { dup/FontType get 0 eq { 1 dict dup/FontName/copied put copyfont begin /FDepVector FDepVector copyarray 0 1 2 index length 1 sub { 2 copy get $deepcopyfont dup/FontName/copied put /copied exch definefont 3 copy put pop pop } for def currentdict end } {$Strategies/$Type3Underprint get exec} ifelse }bind def /$buildfontname { dup/CIDFont findresource/CIDSystemInfo get begin Registry length Ordering length Supplement 8 string cvs 3 copy length 2 add add add string dup 5 1 roll dup 0 Registry putinterval dup 4 index(-)putinterval dup 4 index 1 add Ordering putinterval 4 2 roll add 1 add 2 copy(-)putinterval end 1 add 2 copy 0 exch getinterval $cmapname $fontpat cvs exch anchorsearch {pop pop 3 2 roll putinterval cvn/$cmapname exch def} {pop pop pop pop pop} ifelse length $str 1 index(-)putinterval 1 add $str 1 index $cmapname $fontpat cvs putinterval $cmapname length add $str exch 0 exch getinterval cvn }bind def /$findfontByROS { /$fontname exch def $ROS Registry 2 copy known { get Ordering 2 copy known {get} {pop pop[]} ifelse } {pop pop[]} ifelse false exch { dup/CIDFont resourcestatus { pop pop save 1 index/CIDFont findresource dup/WidthsOnly known {dup/WidthsOnly get} {false} ifelse exch pop exch restore {pop} {exch pop true exit} ifelse } {pop} ifelse } forall {$str cvs $buildfontname} { false(*) { save exch dup/CIDFont findresource dup/WidthsOnly known {dup/WidthsOnly get not} {true} ifelse exch/CIDSystemInfo get dup/Registry get Registry eq exch/Ordering get Ordering eq and and {exch restore exch pop true exit} {pop restore} ifelse } $str/CIDFont resourceforall {$buildfontname} {$fontname $findfontByEnum} ifelse } ifelse }bind def end end currentdict/$error known currentdict/languagelevel known and dup {pop $error/SubstituteFont known} if dup {$error} {Adobe_CoolType_Core} ifelse begin { /SubstituteFont /CMap/Category resourcestatus { pop pop { $SubstituteFont begin /$substituteFound true def dup length $slen gt $sname null ne or $slen 0 gt and { $sname null eq {dup $str cvs dup length $slen sub $slen getinterval cvn} {$sname} ifelse Adobe_CoolType_Data/InVMFontsByCMap get 1 index 2 copy known { get false exch { pop currentglobal { GlobalFontDirectory 1 index known {exch pop true exit} {pop} ifelse } { FontDirectory 1 index known {exch pop true exit} { GlobalFontDirectory 1 index known {exch pop true exit} {pop} ifelse } ifelse } ifelse } forall } {pop pop false} ifelse { exch pop exch pop } { dup/CMap resourcestatus { pop pop dup/$cmapname exch def /CMap findresource/CIDSystemInfo get{def}forall $findfontByROS } { 128 string cvs dup(-)search { 3 1 roll search { 3 1 roll pop {dup cvi} stopped {pop pop pop pop pop $findfontByEnum} { 4 2 roll pop pop exch length exch 2 index length 2 index sub exch 1 sub -1 0 { $str cvs dup length 4 index 0 4 index 4 3 roll add getinterval exch 1 index exch 3 index exch putinterval dup/CMap resourcestatus { pop pop 4 1 roll pop pop pop dup/$cmapname exch def /CMap findresource/CIDSystemInfo get{def}forall $findfontByROS true exit } {pop} ifelse } for dup type/booleantype eq {pop} {pop pop pop $findfontByEnum} ifelse } ifelse } {pop pop pop $findfontByEnum} ifelse } {pop pop $findfontByEnum} ifelse } ifelse } ifelse } {//SubstituteFont exec} ifelse /$slen 0 def end } } { { $SubstituteFont begin /$substituteFound true def dup length $slen gt $sname null ne or $slen 0 gt and {$findfontByEnum} {//SubstituteFont exec} ifelse end } } ifelse bind readonly def Adobe_CoolType_Core/scfindfont/systemfindfont load put } { /scfindfont { $SubstituteFont begin dup systemfindfont dup/FontName known {dup/FontName get dup 3 index ne} {/noname true} ifelse dup { /$origfontnamefound 2 index def /$origfontname 4 index def/$substituteFound true def } if exch pop { $slen 0 gt $sname null ne 3 index length $slen gt or and { pop dup $findfontByEnum findfont dup maxlength 1 add dict begin {1 index/FID eq{pop pop}{def}ifelse} forall currentdict end definefont dup/FontName known{dup/FontName get}{null}ifelse $origfontnamefound ne { $origfontname $str cvs print ( substitution revised, using )print dup/FontName known {dup/FontName get}{(unspecified font)} ifelse $str cvs print(.\n)print } if } {exch pop} ifelse } {exch pop} ifelse end }bind def } ifelse end end Adobe_CoolType_Core_Defined not { Adobe_CoolType_Core/findfont { $SubstituteFont begin $depth 0 eq { /$fontname 1 index dup type/stringtype ne{$str cvs}if def /$substituteFound false def } if /$depth $depth 1 add def end scfindfont $SubstituteFont begin /$depth $depth 1 sub def $substituteFound $depth 0 eq and { $inVMIndex null ne {dup $inVMIndex $AddInVMFont} if $doSmartSub { currentdict/$Strategy known {$Strategy/$BuildFont get exec} if } if } if end }bind put } if } if end /$AddInVMFont { exch/FontName 2 copy known { get 1 dict dup begin exch 1 index gcheck def end exch Adobe_CoolType_Data/InVMFontsByCMap get exch $DictAdd } {pop pop pop} ifelse }bind def /$DictAdd { 2 copy known not {2 copy 4 index length dict put} if Level2? not { 2 copy get dup maxlength exch length 4 index length add lt 2 copy get dup length 4 index length add exch maxlength 1 index lt { 2 mul dict begin 2 copy get{forall}def 2 copy currentdict put end } {pop} ifelse } if get begin {def} forall end }bind def end end %%EndResource currentglobal true setglobal %%BeginResource: procset Adobe_CoolType_Utility_MAKEOCF 1.23 0 %%Copyright: Copyright 1987-2006 Adobe Systems Incorporated. %%Version: 1.23 0 systemdict/languagelevel known dup {currentglobal false setglobal} {false} ifelse exch userdict/Adobe_CoolType_Utility 2 copy known {2 copy get dup maxlength 27 add dict copy} {27 dict} ifelse put Adobe_CoolType_Utility begin /@eexecStartData def /@recognizeCIDFont null def /ct_Level2? exch def /ct_Clone? 1183615869 internaldict dup /CCRun known not exch/eCCRun known not ct_Level2? and or def ct_Level2? {globaldict begin currentglobal true setglobal} if /ct_AddStdCIDMap ct_Level2? {{ mark Adobe_CoolType_Utility/@recognizeCIDFont currentdict put { ((Hex)57 StartData 0615 1e27 2c39 1c60 d8a8 cc31 fe2b f6e0 7aa3 e541 e21c 60d8 a8c9 c3d0 6d9e 1c60 d8a8 c9c2 02d7 9a1c 60d8 a849 1c60 d8a8 cc36 74f4 1144 b13b 77)0()/SubFileDecode filter cvx exec } stopped { cleartomark Adobe_CoolType_Utility/@recognizeCIDFont get countdictstack dup array dictstack exch 1 sub -1 0 { 2 copy get 3 index eq {1 index length exch sub 1 sub{end}repeat exit} {pop} ifelse } for pop pop Adobe_CoolType_Utility/@eexecStartData get eexec } {cleartomark} ifelse }} {{ Adobe_CoolType_Utility/@eexecStartData get eexec }} ifelse bind def userdict/cid_extensions known dup{cid_extensions/cid_UpdateDB known and}if { cid_extensions begin /cid_GetCIDSystemInfo { 1 index type/stringtype eq {exch cvn exch} if cid_extensions begin dup load 2 index known { 2 copy cid_GetStatusInfo dup null ne { 1 index load 3 index get dup null eq {pop pop cid_UpdateDB} { exch 1 index/Created get eq {exch pop exch pop} {pop cid_UpdateDB} ifelse } ifelse } {pop cid_UpdateDB} ifelse } {cid_UpdateDB} ifelse end }bind def end } if ct_Level2? {end setglobal} if /ct_UseNativeCapability? systemdict/composefont known def /ct_MakeOCF 35 dict def /ct_Vars 25 dict def /ct_GlyphDirProcs 6 dict def /ct_BuildCharDict 15 dict dup begin /charcode 2 string def /dst_string 1500 string def /nullstring()def /usewidths? true def end def ct_Level2?{setglobal}{pop}ifelse ct_GlyphDirProcs begin /GetGlyphDirectory { systemdict/languagelevel known {pop/CIDFont findresource/GlyphDirectory get} { 1 index/CIDFont findresource/GlyphDirectory get dup type/dicttype eq { dup dup maxlength exch length sub 2 index lt { dup length 2 index add dict copy 2 index /CIDFont findresource/GlyphDirectory 2 index put } if } if exch pop exch pop } ifelse + }def /+ { systemdict/languagelevel known { currentglobal false setglobal 3 dict begin /vm exch def } {1 dict begin} ifelse /$ exch def systemdict/languagelevel known { vm setglobal /gvm currentglobal def $ gcheck setglobal } if ?{$ begin}if }def /?{$ type/dicttype eq}def /|{ userdict/Adobe_CoolType_Data known { Adobe_CoolType_Data/AddWidths? known { currentdict Adobe_CoolType_Data begin begin AddWidths? { Adobe_CoolType_Data/CC 3 index put ?{def}{$ 3 1 roll put}ifelse CC charcode exch 1 index 0 2 index 256 idiv put 1 index exch 1 exch 256 mod put stringwidth 2 array astore currentfont/Widths get exch CC exch put } {?{def}{$ 3 1 roll put}ifelse} ifelse end end } {?{def}{$ 3 1 roll put}ifelse} ifelse } {?{def}{$ 3 1 roll put}ifelse} ifelse }def /! { ?{end}if systemdict/languagelevel known {gvm setglobal} if end }def /:{string currentfile exch readstring pop}executeonly def end ct_MakeOCF begin /ct_cHexEncoding [/c00/c01/c02/c03/c04/c05/c06/c07/c08/c09/c0A/c0B/c0C/c0D/c0E/c0F/c10/c11/c12 /c13/c14/c15/c16/c17/c18/c19/c1A/c1B/c1C/c1D/c1E/c1F/c20/c21/c22/c23/c24/c25 /c26/c27/c28/c29/c2A/c2B/c2C/c2D/c2E/c2F/c30/c31/c32/c33/c34/c35/c36/c37/c38 /c39/c3A/c3B/c3C/c3D/c3E/c3F/c40/c41/c42/c43/c44/c45/c46/c47/c48/c49/c4A/c4B /c4C/c4D/c4E/c4F/c50/c51/c52/c53/c54/c55/c56/c57/c58/c59/c5A/c5B/c5C/c5D/c5E /c5F/c60/c61/c62/c63/c64/c65/c66/c67/c68/c69/c6A/c6B/c6C/c6D/c6E/c6F/c70/c71 /c72/c73/c74/c75/c76/c77/c78/c79/c7A/c7B/c7C/c7D/c7E/c7F/c80/c81/c82/c83/c84 /c85/c86/c87/c88/c89/c8A/c8B/c8C/c8D/c8E/c8F/c90/c91/c92/c93/c94/c95/c96/c97 /c98/c99/c9A/c9B/c9C/c9D/c9E/c9F/cA0/cA1/cA2/cA3/cA4/cA5/cA6/cA7/cA8/cA9/cAA /cAB/cAC/cAD/cAE/cAF/cB0/cB1/cB2/cB3/cB4/cB5/cB6/cB7/cB8/cB9/cBA/cBB/cBC/cBD /cBE/cBF/cC0/cC1/cC2/cC3/cC4/cC5/cC6/cC7/cC8/cC9/cCA/cCB/cCC/cCD/cCE/cCF/cD0 /cD1/cD2/cD3/cD4/cD5/cD6/cD7/cD8/cD9/cDA/cDB/cDC/cDD/cDE/cDF/cE0/cE1/cE2/cE3 /cE4/cE5/cE6/cE7/cE8/cE9/cEA/cEB/cEC/cED/cEE/cEF/cF0/cF1/cF2/cF3/cF4/cF5/cF6 /cF7/cF8/cF9/cFA/cFB/cFC/cFD/cFE/cFF]def /ct_CID_STR_SIZE 8000 def /ct_mkocfStr100 100 string def /ct_defaultFontMtx[.001 0 0 .001 0 0]def /ct_1000Mtx[1000 0 0 1000 0 0]def /ct_raise{exch cvx exch errordict exch get exec stop}bind def /ct_reraise {cvx $error/errorname get(Error: )print dup( )cvs print errordict exch get exec stop }bind def /ct_cvnsi { 1 index add 1 sub 1 exch 0 4 1 roll { 2 index exch get exch 8 bitshift add } for exch pop }bind def /ct_GetInterval { Adobe_CoolType_Utility/ct_BuildCharDict get begin /dst_index 0 def dup dst_string length gt {dup string/dst_string exch def} if 1 index ct_CID_STR_SIZE idiv /arrayIndex exch def 2 index arrayIndex get 2 index arrayIndex ct_CID_STR_SIZE mul sub { dup 3 index add 2 index length le { 2 index getinterval dst_string dst_index 2 index putinterval length dst_index add/dst_index exch def exit } { 1 index length 1 index sub dup 4 1 roll getinterval dst_string dst_index 2 index putinterval pop dup dst_index add/dst_index exch def sub /arrayIndex arrayIndex 1 add def 2 index dup length arrayIndex gt {arrayIndex get} { pop exit } ifelse 0 } ifelse } loop pop pop pop dst_string 0 dst_index getinterval end }bind def ct_Level2? { /ct_resourcestatus currentglobal mark true setglobal {/unknowninstancename/Category resourcestatus} stopped {cleartomark setglobal true} {cleartomark currentglobal not exch setglobal} ifelse { { mark 3 1 roll/Category findresource begin ct_Vars/vm currentglobal put ({ResourceStatus}stopped)0()/SubFileDecode filter cvx exec {cleartomark false} {{3 2 roll pop true}{cleartomark false}ifelse} ifelse ct_Vars/vm get setglobal end } } {{resourcestatus}} ifelse bind def /CIDFont/Category ct_resourcestatus {pop pop} { currentglobal true setglobal /Generic/Category findresource dup length dict copy dup/InstanceType/dicttype put /CIDFont exch/Category defineresource pop setglobal } ifelse ct_UseNativeCapability? { /CIDInit/ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo 3 dict dup begin /Registry(Adobe)def /Ordering(Identity)def /Supplement 0 def end def /CMapName/Identity-H def /CMapVersion 1.000 def /CMapType 1 def 1 begincodespacerange <0000> endcodespacerange 1 begincidrange <0000>0 endcidrange endcmap CMapName currentdict/CMap defineresource pop end end } if } { /ct_Category 2 dict begin /CIDFont 10 dict def /ProcSet 2 dict def currentdict end def /defineresource { ct_Category 1 index 2 copy known { get dup dup maxlength exch length eq { dup length 10 add dict copy ct_Category 2 index 2 index put } if 3 index 3 index put pop exch pop } {pop pop/defineresource/undefined ct_raise} ifelse }bind def /findresource { ct_Category 1 index 2 copy known { get 2 index 2 copy known {get 3 1 roll pop pop} {pop pop/findresource/undefinedresource ct_raise} ifelse } {pop pop/findresource/undefined ct_raise} ifelse }bind def /resourcestatus { ct_Category 1 index 2 copy known { get 2 index known exch pop exch pop { 0 -1 true } { false } ifelse } {pop pop/findresource/undefined ct_raise} ifelse }bind def /ct_resourcestatus/resourcestatus load def } ifelse /ct_CIDInit 2 dict begin /ct_cidfont_stream_init { { dup(Binary)eq { pop null currentfile ct_Level2? { {cid_BYTE_COUNT()/SubFileDecode filter} stopped {pop pop pop} if } if /readstring load exit } if dup(Hex)eq { pop currentfile ct_Level2? { {null exch/ASCIIHexDecode filter/readstring} stopped {pop exch pop(>)exch/readhexstring} if } {(>)exch/readhexstring} ifelse load exit } if /StartData/typecheck ct_raise } loop cid_BYTE_COUNT ct_CID_STR_SIZE le { 2 copy cid_BYTE_COUNT string exch exec pop 1 array dup 3 -1 roll 0 exch put } { cid_BYTE_COUNT ct_CID_STR_SIZE div ceiling cvi dup array exch 2 sub 0 exch 1 exch { 2 copy 5 index ct_CID_STR_SIZE string 6 index exec pop put pop } for 2 index cid_BYTE_COUNT ct_CID_STR_SIZE mod string 3 index exec pop 1 index exch 1 index length 1 sub exch put } ifelse cid_CIDFONT exch/GlyphData exch put 2 index null eq { pop pop pop } { pop/readstring load 1 string exch { 3 copy exec pop dup length 0 eq { pop pop pop pop pop true exit } if 4 index eq { pop pop pop pop false exit } if } loop pop } ifelse }bind def /StartData { mark { currentdict dup/FDArray get 0 get/FontMatrix get 0 get 0.001 eq { dup/CDevProc known not { /CDevProc 1183615869 internaldict/stdCDevProc 2 copy known {get} { pop pop {pop pop pop pop pop 0 -1000 7 index 2 div 880} } ifelse def } if } { /CDevProc { pop pop pop pop pop 0 1 cid_temp/cid_CIDFONT get /FDArray get 0 get /FontMatrix get 0 get div 7 index 2 div 1 index 0.88 mul }def } ifelse /cid_temp 15 dict def cid_temp begin /cid_CIDFONT exch def 3 copy pop dup/cid_BYTE_COUNT exch def 0 gt { ct_cidfont_stream_init FDArray { /Private get dup/SubrMapOffset known { begin /Subrs SubrCount array def Subrs SubrMapOffset SubrCount SDBytes ct_Level2? { currentdict dup/SubrMapOffset undef dup/SubrCount undef /SDBytes undef } if end /cid_SD_BYTES exch def /cid_SUBR_COUNT exch def /cid_SUBR_MAP_OFFSET exch def /cid_SUBRS exch def cid_SUBR_COUNT 0 gt { GlyphData cid_SUBR_MAP_OFFSET cid_SD_BYTES ct_GetInterval 0 cid_SD_BYTES ct_cvnsi 0 1 cid_SUBR_COUNT 1 sub { exch 1 index 1 add cid_SD_BYTES mul cid_SUBR_MAP_OFFSET add GlyphData exch cid_SD_BYTES ct_GetInterval 0 cid_SD_BYTES ct_cvnsi cid_SUBRS 4 2 roll GlyphData exch 4 index 1 index sub ct_GetInterval dup length string copy put } for pop } if } {pop} ifelse } forall } if cleartomark pop pop end CIDFontName currentdict/CIDFont defineresource pop end end } stopped {cleartomark/StartData ct_reraise} if }bind def currentdict end def /ct_saveCIDInit { /CIDInit/ProcSet ct_resourcestatus {true} {/CIDInitC/ProcSet ct_resourcestatus} ifelse { pop pop /CIDInit/ProcSet findresource ct_UseNativeCapability? {pop null} {/CIDInit ct_CIDInit/ProcSet defineresource pop} ifelse } {/CIDInit ct_CIDInit/ProcSet defineresource pop null} ifelse ct_Vars exch/ct_oldCIDInit exch put }bind def /ct_restoreCIDInit { ct_Vars/ct_oldCIDInit get dup null ne {/CIDInit exch/ProcSet defineresource pop} {pop} ifelse }bind def /ct_BuildCharSetUp { 1 index begin CIDFont begin Adobe_CoolType_Utility/ct_BuildCharDict get begin /ct_dfCharCode exch def /ct_dfDict exch def CIDFirstByte ct_dfCharCode add dup CIDCount ge {pop 0} if /cid exch def { GlyphDirectory cid 2 copy known {get} {pop pop nullstring} ifelse dup length FDBytes sub 0 gt { dup FDBytes 0 ne {0 FDBytes ct_cvnsi} {pop 0} ifelse /fdIndex exch def dup length FDBytes sub FDBytes exch getinterval /charstring exch def exit } { pop cid 0 eq {/charstring nullstring def exit} if /cid 0 def } ifelse } loop }def /ct_SetCacheDevice { 0 0 moveto dup stringwidth 3 -1 roll true charpath pathbbox 0 -1000 7 index 2 div 880 setcachedevice2 0 0 moveto }def /ct_CloneSetCacheProc { 1 eq { stringwidth pop -2 div -880 0 -1000 setcharwidth moveto } { usewidths? { currentfont/Widths get cid 2 copy known {get exch pop aload pop} {pop pop stringwidth} ifelse } {stringwidth} ifelse setcharwidth 0 0 moveto } ifelse }def /ct_Type3ShowCharString { ct_FDDict fdIndex 2 copy known {get} { currentglobal 3 1 roll 1 index gcheck setglobal ct_Type1FontTemplate dup maxlength dict copy begin FDArray fdIndex get dup/FontMatrix 2 copy known {get} {pop pop ct_defaultFontMtx} ifelse /FontMatrix exch dup length array copy def /Private get /Private exch def /Widths rootfont/Widths get def /CharStrings 1 dict dup/.notdef dup length string copy put def currentdict end /ct_Type1Font exch definefont dup 5 1 roll put setglobal } ifelse dup/CharStrings get 1 index/Encoding get ct_dfCharCode get charstring put rootfont/WMode 2 copy known {get} {pop pop 0} ifelse exch 1000 scalefont setfont ct_str1 0 ct_dfCharCode put ct_str1 exch ct_dfSetCacheProc ct_SyntheticBold { currentpoint ct_str1 show newpath moveto ct_str1 true charpath ct_StrokeWidth setlinewidth stroke } {ct_str1 show} ifelse }def /ct_Type4ShowCharString { ct_dfDict ct_dfCharCode charstring FDArray fdIndex get dup/FontMatrix get dup ct_defaultFontMtx ct_matrixeq not {ct_1000Mtx matrix concatmatrix concat} {pop} ifelse /Private get Adobe_CoolType_Utility/ct_Level2? get not { ct_dfDict/Private 3 -1 roll {put} 1183615869 internaldict/superexec get exec } if 1183615869 internaldict Adobe_CoolType_Utility/ct_Level2? get {1 index} {3 index/Private get mark 6 1 roll} ifelse dup/RunInt known {/RunInt get} {pop/CCRun} ifelse get exec Adobe_CoolType_Utility/ct_Level2? get not {cleartomark} if }bind def /ct_BuildCharIncremental { { Adobe_CoolType_Utility/ct_MakeOCF get begin ct_BuildCharSetUp ct_ShowCharString } stopped {stop} if end end end end }bind def /BaseFontNameStr(BF00)def /ct_Type1FontTemplate 14 dict begin /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0]def /FontBBox [-250 -250 1250 1250]def /Encoding ct_cHexEncoding def /PaintType 0 def currentdict end def /BaseFontTemplate 11 dict begin /FontMatrix [0.001 0 0 0.001 0 0]def /FontBBox [-250 -250 1250 1250]def /Encoding ct_cHexEncoding def /BuildChar/ct_BuildCharIncremental load def ct_Clone? { /FontType 3 def /ct_ShowCharString/ct_Type3ShowCharString load def /ct_dfSetCacheProc/ct_CloneSetCacheProc load def /ct_SyntheticBold false def /ct_StrokeWidth 1 def } { /FontType 4 def /Private 1 dict dup/lenIV 4 put def /CharStrings 1 dict dup/.notdefput def /PaintType 0 def /ct_ShowCharString/ct_Type4ShowCharString load def } ifelse /ct_str1 1 string def currentdict end def /BaseFontDictSize BaseFontTemplate length 5 add def /ct_matrixeq { true 0 1 5 { dup 4 index exch get exch 3 index exch get eq and dup not {exit} if } for exch pop exch pop }bind def /ct_makeocf { 15 dict begin exch/WMode exch def exch/FontName exch def /FontType 0 def /FMapType 2 def dup/FontMatrix known {dup/FontMatrix get/FontMatrix exch def} {/FontMatrix matrix def} ifelse /bfCount 1 index/CIDCount get 256 idiv 1 add dup 256 gt{pop 256}if def /Encoding 256 array 0 1 bfCount 1 sub{2 copy dup put pop}for bfCount 1 255{2 copy bfCount put pop}for def /FDepVector bfCount dup 256 lt{1 add}if array def BaseFontTemplate BaseFontDictSize dict copy begin /CIDFont exch def CIDFont/FontBBox known {CIDFont/FontBBox get/FontBBox exch def} if CIDFont/CDevProc known {CIDFont/CDevProc get/CDevProc exch def} if currentdict end BaseFontNameStr 3(0)putinterval 0 1 bfCount dup 256 eq{1 sub}if { FDepVector exch 2 index BaseFontDictSize dict copy begin dup/CIDFirstByte exch 256 mul def FontType 3 eq {/ct_FDDict 2 dict def} if currentdict end 1 index 16 BaseFontNameStr 2 2 getinterval cvrs pop BaseFontNameStr exch definefont put } for ct_Clone? {/Widths 1 index/CIDFont get/GlyphDirectory get length dict def} if FontName currentdict end definefont ct_Clone? { gsave dup 1000 scalefont setfont ct_BuildCharDict begin /usewidths? false def currentfont/Widths get begin exch/CIDFont get/GlyphDirectory get { pop dup charcode exch 1 index 0 2 index 256 idiv put 1 index exch 1 exch 256 mod put stringwidth 2 array astore def } forall end /usewidths? true def end grestore } {exch pop} ifelse }bind def currentglobal true setglobal /ct_ComposeFont { ct_UseNativeCapability? { 2 index/CMap ct_resourcestatus {pop pop exch pop} { /CIDInit/ProcSet findresource begin 12 dict begin begincmap /CMapName 3 index def /CMapVersion 1.000 def /CMapType 1 def exch/WMode exch def /CIDSystemInfo 3 dict dup begin /Registry(Adobe)def /Ordering CMapName ct_mkocfStr100 cvs (Adobe-)search { pop pop (-)search { dup length string copy exch pop exch pop } {pop(Identity)} ifelse } {pop (Identity)} ifelse def /Supplement 0 def end def 1 begincodespacerange <0000> endcodespacerange 1 begincidrange <0000>0 endcidrange endcmap CMapName currentdict/CMap defineresource pop end end } ifelse composefont } { 3 2 roll pop 0 get/CIDFont findresource ct_makeocf } ifelse }bind def setglobal /ct_MakeIdentity { ct_UseNativeCapability? { 1 index/CMap ct_resourcestatus {pop pop} { /CIDInit/ProcSet findresource begin 12 dict begin begincmap /CMapName 2 index def /CMapVersion 1.000 def /CMapType 1 def /CIDSystemInfo 3 dict dup begin /Registry(Adobe)def /Ordering CMapName ct_mkocfStr100 cvs (Adobe-)search { pop pop (-)search {dup length string copy exch pop exch pop} {pop(Identity)} ifelse } {pop(Identity)} ifelse def /Supplement 0 def end def 1 begincodespacerange <0000> endcodespacerange 1 begincidrange <0000>0 endcidrange endcmap CMapName currentdict/CMap defineresource pop end end } ifelse composefont } { exch pop 0 get/CIDFont findresource ct_makeocf } ifelse }bind def currentdict readonly pop end end %%EndResource setglobal %%BeginResource: procset Adobe_CoolType_Utility_T42 1.0 0 %%Copyright: Copyright 1987-2004 Adobe Systems Incorporated. %%Version: 1.0 0 userdict/ct_T42Dict 15 dict put ct_T42Dict begin /Is2015? { version cvi 2015 ge }bind def /AllocGlyphStorage { Is2015? { pop } { {string}forall }ifelse }bind def /Type42DictBegin { 25 dict begin /FontName exch def /CharStrings 256 dict begin /.notdef 0 def currentdict end def /Encoding exch def /PaintType 0 def /FontType 42 def /FontMatrix[1 0 0 1 0 0]def 4 array astore cvx/FontBBox exch def /sfnts }bind def /Type42DictEnd { currentdict dup/FontName get exch definefont end ct_T42Dict exch dup/FontName get exch put }bind def /RD{string currentfile exch readstring pop}executeonly def /PrepFor2015 { Is2015? { /GlyphDirectory 16 dict def sfnts 0 get dup 2 index (glyx) putinterval 2 index (locx) putinterval pop pop } { pop pop }ifelse }bind def /AddT42Char { Is2015? { /GlyphDirectory get begin def end pop pop } { /sfnts get 4 index get 3 index 2 index putinterval pop pop pop pop }ifelse }bind def /T0AddT42Mtx2 { /CIDFont findresource/Metrics2 get begin def end }bind def end %%EndResource currentglobal true setglobal %%BeginFile: MMFauxFont.prc %%Copyright: Copyright 1987-2001 Adobe Systems Incorporated. %%All Rights Reserved. userdict /ct_EuroDict 10 dict put ct_EuroDict begin /ct_CopyFont { { 1 index /FID ne {def} {pop pop} ifelse} forall } def /ct_GetGlyphOutline { gsave initmatrix newpath exch findfont dup length 1 add dict begin ct_CopyFont /Encoding Encoding dup length array copy dup 4 -1 roll 0 exch put def currentdict end /ct_EuroFont exch definefont 1000 scalefont setfont 0 0 moveto [ <00> stringwidth <00> false charpath pathbbox [ {/m cvx} {/l cvx} {/c cvx} {/cp cvx} pathforall grestore counttomark 8 add } def /ct_MakeGlyphProc { ] cvx /ct_PSBuildGlyph cvx ] cvx } def /ct_PSBuildGlyph { gsave 8 -1 roll pop 7 1 roll 6 -2 roll ct_FontMatrix transform 6 2 roll 4 -2 roll ct_FontMatrix transform 4 2 roll ct_FontMatrix transform currentdict /PaintType 2 copy known {get 2 eq}{pop pop false} ifelse dup 9 1 roll { currentdict /StrokeWidth 2 copy known { get 2 div 0 ct_FontMatrix dtransform pop 5 1 roll 4 -1 roll 4 index sub 4 1 roll 3 -1 roll 4 index sub 3 1 roll exch 4 index add exch 4 index add 5 -1 roll pop } { pop pop } ifelse } if setcachedevice ct_FontMatrix concat ct_PSPathOps begin exec end { currentdict /StrokeWidth 2 copy known { get } { pop pop 0 } ifelse setlinewidth stroke } { fill } ifelse grestore } def /ct_PSPathOps 4 dict dup begin /m {moveto} def /l {lineto} def /c {curveto} def /cp {closepath} def end def /ct_matrix1000 [1000 0 0 1000 0 0] def /ct_AddGlyphProc { 2 index findfont dup length 4 add dict begin ct_CopyFont /CharStrings CharStrings dup length 1 add dict copy begin 3 1 roll def currentdict end def /ct_FontMatrix ct_matrix1000 FontMatrix matrix concatmatrix def /ct_PSBuildGlyph /ct_PSBuildGlyph load def /ct_PSPathOps /ct_PSPathOps load def currentdict end definefont pop } def systemdict /languagelevel known { /ct_AddGlyphToPrinterFont { 2 copy ct_GetGlyphOutline 3 add -1 roll restore ct_MakeGlyphProc ct_AddGlyphProc } def } { /ct_AddGlyphToPrinterFont { pop pop restore Adobe_CTFauxDict /$$$FONTNAME get /Euro Adobe_CTFauxDict /$$$SUBSTITUTEBASE get ct_EuroDict exch get ct_AddGlyphProc } def } ifelse /AdobeSansMM { 556 0 24 -19 541 703 { 541 628 m 510 669 442 703 354 703 c 201 703 117 607 101 444 c 50 444 l 25 372 l 97 372 l 97 301 l 49 301 l 24 229 l 103 229 l 124 67 209 -19 350 -19 c 435 -19 501 25 509 32 c 509 131 l 492 105 417 60 343 60 c 267 60 204 127 197 229 c 406 229 l 430 301 l 191 301 l 191 372 l 455 372 l 479 444 l 194 444 l 201 531 245 624 348 624 c 433 624 484 583 509 534 c cp 556 0 m } ct_PSBuildGlyph } def /AdobeSerifMM { 500 0 10 -12 484 692 { 347 298 m 171 298 l 170 310 170 322 170 335 c 170 362 l 362 362 l 374 403 l 172 403 l 184 580 244 642 308 642 c 380 642 434 574 457 457 c 481 462 l 474 691 l 449 691 l 433 670 429 657 410 657 c 394 657 360 692 299 692 c 204 692 94 604 73 403 c 22 403 l 10 362 l 70 362 l 69 352 69 341 69 330 c 69 319 69 308 70 298 c 22 298 l 10 257 l 73 257 l 97 57 216 -12 295 -12 c 364 -12 427 25 484 123 c 458 142 l 425 101 384 37 316 37 c 256 37 189 84 173 257 c 335 257 l cp 500 0 m } ct_PSBuildGlyph } def end %%EndFile setglobal Adobe_CoolType_Core begin /$Oblique SetSubstituteStrategy end %%BeginResource: procset Adobe_AGM_Image 1.0 0 %%Version: 1.0 0 %%Copyright: Copyright(C)2000-2006 Adobe Systems, Inc. All Rights Reserved. systemdict/setpacking known { currentpacking true setpacking }if userdict/Adobe_AGM_Image 71 dict dup begin put /Adobe_AGM_Image_Id/Adobe_AGM_Image_1.0_0 def /nd{ null def }bind def /AGMIMG_&image nd /AGMIMG_&colorimage nd /AGMIMG_&imagemask nd /AGMIMG_mbuf()def /AGMIMG_ybuf()def /AGMIMG_kbuf()def /AGMIMG_c 0 def /AGMIMG_m 0 def /AGMIMG_y 0 def /AGMIMG_k 0 def /AGMIMG_tmp nd /AGMIMG_imagestring0 nd /AGMIMG_imagestring1 nd /AGMIMG_imagestring2 nd /AGMIMG_imagestring3 nd /AGMIMG_imagestring4 nd /AGMIMG_imagestring5 nd /AGMIMG_cnt nd /AGMIMG_fsave nd /AGMIMG_colorAry nd /AGMIMG_override nd /AGMIMG_name nd /AGMIMG_maskSource nd /AGMIMG_flushfilters nd /invert_image_samples nd /knockout_image_samples nd /img nd /sepimg nd /devnimg nd /idximg nd /ds { Adobe_AGM_Core begin Adobe_AGM_Image begin /AGMIMG_&image systemdict/image get def /AGMIMG_&imagemask systemdict/imagemask get def /colorimage where{ pop /AGMIMG_&colorimage/colorimage ldf }if end end }def /ps { Adobe_AGM_Image begin /AGMIMG_ccimage_exists{/customcolorimage where { pop /Adobe_AGM_OnHost_Seps where { pop false }{ /Adobe_AGM_InRip_Seps where { pop false }{ true }ifelse }ifelse }{ false }ifelse }bdf level2{ /invert_image_samples { Adobe_AGM_Image/AGMIMG_tmp Decode length ddf /Decode[Decode 1 get Decode 0 get]def }def /knockout_image_samples { Operator/imagemask ne{ /Decode[1 1]def }if }def }{ /invert_image_samples { {1 exch sub}currenttransfer addprocs settransfer }def /knockout_image_samples { {pop 1}currenttransfer addprocs settransfer }def }ifelse /img/imageormask ldf /sepimg/sep_imageormask ldf /devnimg/devn_imageormask ldf /idximg/indexed_imageormask ldf /_ctype 7 def currentdict{ dup xcheck 1 index type dup/arraytype eq exch/packedarraytype eq or and{ bind }if def }forall }def /pt { end }def /dt { }def /AGMIMG_flushfilters { dup type/arraytype ne {1 array astore}if dup 0 get currentfile ne {dup 0 get flushfile}if { dup type/filetype eq { dup status 1 index currentfile ne and {closefile} {pop} ifelse }{pop}ifelse }forall }def /AGMIMG_init_common { currentdict/T known{/ImageType/T ldf currentdict/T undef}if currentdict/W known{/Width/W ldf currentdict/W undef}if currentdict/H known{/Height/H ldf currentdict/H undef}if currentdict/M known{/ImageMatrix/M ldf currentdict/M undef}if currentdict/BC known{/BitsPerComponent/BC ldf currentdict/BC undef}if currentdict/D known{/Decode/D ldf currentdict/D undef}if currentdict/DS known{/DataSource/DS ldf currentdict/DS undef}if currentdict/O known{ /Operator/O load 1 eq{ /imagemask }{ /O load 2 eq{ /image }{ /colorimage }ifelse }ifelse def currentdict/O undef }if currentdict/HSCI known{/HostSepColorImage/HSCI ldf currentdict/HSCI undef}if currentdict/MD known{/MultipleDataSources/MD ldf currentdict/MD undef}if currentdict/I known{/Interpolate/I ldf currentdict/I undef}if currentdict/SI known{/SkipImageProc/SI ldf currentdict/SI undef}if /DataSource load xcheck not{ DataSource type/arraytype eq{ DataSource 0 get type/filetype eq{ /_Filters DataSource def currentdict/MultipleDataSources known not{ /DataSource DataSource dup length 1 sub get def }if }if }if currentdict/MultipleDataSources known not{ /MultipleDataSources DataSource type/arraytype eq{ DataSource length 1 gt } {false}ifelse def }if }if /NComponents Decode length 2 div def currentdict/SkipImageProc known not{/SkipImageProc{false}def}if }bdf /imageormask_sys { begin AGMIMG_init_common save mark level2{ currentdict Operator/imagemask eq{ AGMIMG_&imagemask }{ use_mask{ process_mask AGMIMG_&image }{ AGMIMG_&image }ifelse }ifelse }{ Width Height Operator/imagemask eq{ Decode 0 get 1 eq Decode 1 get 0 eq and ImageMatrix/DataSource load AGMIMG_&imagemask }{ BitsPerComponent ImageMatrix/DataSource load AGMIMG_&image }ifelse }ifelse currentdict/_Filters known{_Filters AGMIMG_flushfilters}if cleartomark restore end }def /overprint_plate { currentoverprint{ 0 get dup type/nametype eq{ dup/DeviceGray eq{ pop AGMCORE_black_plate not }{ /DeviceCMYK eq{ AGMCORE_is_cmyk_sep not }if }ifelse }{ false exch { AGMOHS_sepink eq or }forall not }ifelse }{ pop false }ifelse }def /process_mask { level3{ dup begin /ImageType 1 def end 4 dict begin /DataDict exch def /ImageType 3 def /InterleaveType 3 def /MaskDict 9 dict begin /ImageType 1 def /Width DataDict dup/MaskWidth known{/MaskWidth}{/Width}ifelse get def /Height DataDict dup/MaskHeight known{/MaskHeight}{/Height}ifelse get def /ImageMatrix[Width 0 0 Height neg 0 Height]def /NComponents 1 def /BitsPerComponent 1 def /Decode DataDict dup/MaskD known{/MaskD}{[1 0]}ifelse get def /DataSource Adobe_AGM_Core/AGMIMG_maskSource get def currentdict end def currentdict end }if }def /use_mask { dup/Mask known {dup/Mask get}{false}ifelse }def /imageormask { begin AGMIMG_init_common SkipImageProc{ currentdict consumeimagedata } { save mark level2 AGMCORE_host_sep not and{ currentdict Operator/imagemask eq DeviceN_PS2 not and{ imagemask }{ AGMCORE_in_rip_sep currentoverprint and currentcolorspace 0 get/DeviceGray eq and{ [/Separation/Black/DeviceGray{}]setcolorspace /Decode[Decode 1 get Decode 0 get]def }if use_mask{ process_mask image }{ DeviceN_NoneName DeviceN_PS2 Indexed_DeviceN level3 not and or or AGMCORE_in_rip_sep and { Names convert_to_process not{ 2 dict begin /imageDict xdf /names_index 0 def gsave imageDict write_image_file{ Names{ dup(None)ne{ [/Separation 3 -1 roll/DeviceGray{1 exch sub}]setcolorspace Operator imageDict read_image_file names_index 0 eq{true setoverprint}if /names_index names_index 1 add def }{ pop }ifelse }forall close_image_file }if grestore end }{ Operator/imagemask eq{ imagemask }{ image }ifelse }ifelse }{ Operator/imagemask eq{ imagemask }{ image }ifelse }ifelse }ifelse }ifelse }{ Width Height Operator/imagemask eq{ Decode 0 get 1 eq Decode 1 get 0 eq and ImageMatrix/DataSource load /Adobe_AGM_OnHost_Seps where{ pop imagemask }{ currentgray 1 ne{ currentdict imageormask_sys }{ currentoverprint not{ 1 AGMCORE_&setgray currentdict imageormask_sys }{ currentdict ignoreimagedata }ifelse }ifelse }ifelse }{ BitsPerComponent ImageMatrix MultipleDataSources{ 0 1 NComponents 1 sub{ DataSource exch get }for }{ /DataSource load }ifelse Operator/colorimage eq{ AGMCORE_host_sep{ MultipleDataSources level2 or NComponents 4 eq and{ AGMCORE_is_cmyk_sep{ MultipleDataSources{ /DataSource DataSource 0 get xcheck { [ DataSource 0 get/exec cvx DataSource 1 get/exec cvx DataSource 2 get/exec cvx DataSource 3 get/exec cvx /AGMCORE_get_ink_data cvx ]cvx }{ DataSource aload pop AGMCORE_get_ink_data }ifelse def }{ /DataSource Width BitsPerComponent mul 7 add 8 idiv Height mul 4 mul /DataSource load filter_cmyk 0()/SubFileDecode filter def }ifelse /Decode[Decode 0 get Decode 1 get]def /MultipleDataSources false def /NComponents 1 def /Operator/image def invert_image_samples 1 AGMCORE_&setgray currentdict imageormask_sys }{ currentoverprint not Operator/imagemask eq and{ 1 AGMCORE_&setgray currentdict imageormask_sys }{ currentdict ignoreimagedata }ifelse }ifelse }{ MultipleDataSources NComponents AGMIMG_&colorimage }ifelse }{ true NComponents colorimage }ifelse }{ Operator/image eq{ AGMCORE_host_sep{ /DoImage true def currentdict/HostSepColorImage known{HostSepColorImage not}{false}ifelse { AGMCORE_black_plate not Operator/imagemask ne and{ /DoImage false def currentdict ignoreimagedata }if }if 1 AGMCORE_&setgray DoImage {currentdict imageormask_sys}if }{ use_mask{ process_mask image }{ image }ifelse }ifelse }{ Operator/knockout eq{ pop pop pop pop pop currentcolorspace overprint_plate not{ knockout_unitsq }if }if }ifelse }ifelse }ifelse }ifelse cleartomark restore }ifelse currentdict/_Filters known{_Filters AGMIMG_flushfilters}if end }def /sep_imageormask { /sep_colorspace_dict AGMCORE_gget begin CSA map_csa begin AGMIMG_init_common SkipImageProc{ currentdict consumeimagedata }{ save mark AGMCORE_avoid_L2_sep_space{ /Decode[Decode 0 get 255 mul Decode 1 get 255 mul]def }if AGMIMG_ccimage_exists MappedCSA 0 get/DeviceCMYK eq and currentdict/Components known and Name()ne and Name(All)ne and Operator/image eq and AGMCORE_producing_seps not and level2 not and { Width Height BitsPerComponent ImageMatrix [ /DataSource load/exec cvx { 0 1 2 index length 1 sub{ 1 index exch 2 copy get 255 xor put }for }/exec cvx ]cvx bind MappedCSA 0 get/DeviceCMYK eq{ Components aload pop }{ 0 0 0 Components aload pop 1 exch sub }ifelse Name findcmykcustomcolor customcolorimage }{ AGMCORE_producing_seps not{ level2{ //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 2 ne AGMCORE_avoid_L2_sep_space not and currentcolorspace 0 get/Separation ne and{ [/Separation Name MappedCSA sep_proc_name exch dup 0 get 15 string cvs(/Device)anchorsearch{pop pop 0 get}{pop}ifelse exch load]setcolorspace_opt /sep_tint AGMCORE_gget setcolor }if currentdict imageormask }{ currentdict Operator/imagemask eq{ imageormask }{ sep_imageormask_lev1 }ifelse }ifelse }{ AGMCORE_host_sep{ Operator/knockout eq{ currentdict/ImageMatrix get concat knockout_unitsq }{ currentgray 1 ne{ AGMCORE_is_cmyk_sep Name(All)ne and{ level2{ Name AGMCORE_IsSeparationAProcessColor { Operator/imagemask eq{ //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 2 ne{ /sep_tint AGMCORE_gget 1 exch sub AGMCORE_&setcolor }if }{ invert_image_samples }ifelse }{ //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 2 ne{ [/Separation Name[/DeviceGray] { sep_colorspace_proc AGMCORE_get_ink_data 1 exch sub }bind ]AGMCORE_&setcolorspace /sep_tint AGMCORE_gget AGMCORE_&setcolor }if }ifelse currentdict imageormask_sys }{ currentdict Operator/imagemask eq{ imageormask_sys }{ sep_image_lev1_sep }ifelse }ifelse }{ Operator/imagemask ne{ invert_image_samples }if currentdict imageormask_sys }ifelse }{ currentoverprint not Name(All)eq or Operator/imagemask eq and{ currentdict imageormask_sys }{ currentoverprint not { gsave knockout_unitsq grestore }if currentdict consumeimagedata }ifelse }ifelse }ifelse }{ //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 2 ne{ currentcolorspace 0 get/Separation ne{ [/Separation Name MappedCSA sep_proc_name exch 0 get exch load]setcolorspace_opt /sep_tint AGMCORE_gget setcolor }if }if currentoverprint MappedCSA 0 get/DeviceCMYK eq and Name AGMCORE_IsSeparationAProcessColor not and //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 2 ne{Name inRip_spot_has_ink not and}{false}ifelse Name(All)ne and{ imageormask_l2_overprint }{ currentdict imageormask }ifelse }ifelse }ifelse }ifelse cleartomark restore }ifelse currentdict/_Filters known{_Filters AGMIMG_flushfilters}if end end }def /colorSpaceElemCnt { mark currentcolor counttomark dup 2 add 1 roll cleartomark }bdf /devn_sep_datasource { 1 dict begin /dataSource xdf [ 0 1 dataSource length 1 sub{ dup currentdict/dataSource get/exch cvx/get cvx/exec cvx /exch cvx names_index/ne cvx[/pop cvx]cvx/if cvx }for ]cvx bind end }bdf /devn_alt_datasource { 11 dict begin /convProc xdf /origcolorSpaceElemCnt xdf /origMultipleDataSources xdf /origBitsPerComponent xdf /origDecode xdf /origDataSource xdf /dsCnt origMultipleDataSources{origDataSource length}{1}ifelse def /DataSource origMultipleDataSources { [ BitsPerComponent 8 idiv origDecode length 2 idiv mul string 0 1 origDecode length 2 idiv 1 sub { dup 7 mul 1 add index exch dup BitsPerComponent 8 idiv mul exch origDataSource exch get 0()/SubFileDecode filter BitsPerComponent 8 idiv string/readstring cvx/pop cvx/putinterval cvx }for ]bind cvx }{origDataSource}ifelse 0()/SubFileDecode filter def [ origcolorSpaceElemCnt string 0 2 origDecode length 2 sub { dup origDecode exch get dup 3 -1 roll 1 add origDecode exch get exch sub 2 BitsPerComponent exp 1 sub div 1 BitsPerComponent 8 idiv{DataSource/read cvx/not cvx{0}/if cvx/mul cvx}repeat/mul cvx/add cvx }for /convProc load/exec cvx origcolorSpaceElemCnt 1 sub -1 0 { /dup cvx 2/add cvx/index cvx 3 1/roll cvx/exch cvx 255/mul cvx/cvi cvx/put cvx }for ]bind cvx 0()/SubFileDecode filter end }bdf /devn_imageormask { /devicen_colorspace_dict AGMCORE_gget begin CSA map_csa 2 dict begin dup /srcDataStrs[3 -1 roll begin AGMIMG_init_common currentdict/MultipleDataSources known{MultipleDataSources{DataSource length}{1}ifelse}{1}ifelse { Width Decode length 2 div mul cvi { dup 65535 gt{1 add 2 div cvi}{exit}ifelse }loop string }repeat end]def /dstDataStr srcDataStrs 0 get length string def begin AGMIMG_init_common SkipImageProc{ currentdict consumeimagedata }{ save mark AGMCORE_producing_seps not{ level3 not{ Operator/imagemask ne{ /DataSource[[ DataSource Decode BitsPerComponent currentdict/MultipleDataSources known{MultipleDataSources}{false}ifelse colorSpaceElemCnt/devicen_colorspace_dict AGMCORE_gget/TintTransform get devn_alt_datasource 1/string cvx/readstring cvx/pop cvx]cvx colorSpaceElemCnt 1 sub{dup}repeat]def /MultipleDataSources true def /Decode colorSpaceElemCnt[exch{0 1}repeat]def }if }if currentdict imageormask }{ AGMCORE_host_sep{ Names convert_to_process{ CSA get_csa_by_name 0 get/DeviceCMYK eq{ /DataSource Width BitsPerComponent mul 7 add 8 idiv Height mul 4 mul DataSource Decode BitsPerComponent currentdict/MultipleDataSources known{MultipleDataSources}{false}ifelse 4/devicen_colorspace_dict AGMCORE_gget/TintTransform get devn_alt_datasource filter_cmyk 0()/SubFileDecode filter def /MultipleDataSources false def /Decode[1 0]def /DeviceGray setcolorspace currentdict imageormask_sys }{ AGMCORE_report_unsupported_color_space AGMCORE_black_plate{ /DataSource DataSource Decode BitsPerComponent currentdict/MultipleDataSources known{MultipleDataSources}{false}ifelse CSA get_csa_by_name 0 get/DeviceRGB eq{3}{1}ifelse/devicen_colorspace_dict AGMCORE_gget/TintTransform get devn_alt_datasource /MultipleDataSources false def /Decode colorSpaceElemCnt[exch{0 1}repeat]def currentdict imageormask_sys }{ gsave knockout_unitsq grestore currentdict consumeimagedata }ifelse }ifelse } { /devicen_colorspace_dict AGMCORE_gget/names_index known{ Operator/imagemask ne{ MultipleDataSources{ /DataSource[DataSource devn_sep_datasource/exec cvx]cvx def /MultipleDataSources false def }{ /DataSource/DataSource load dstDataStr srcDataStrs 0 get filter_devn def }ifelse invert_image_samples }if currentdict imageormask_sys }{ currentoverprint not Operator/imagemask eq and{ currentdict imageormask_sys }{ currentoverprint not { gsave knockout_unitsq grestore }if currentdict consumeimagedata }ifelse }ifelse }ifelse }{ currentdict imageormask }ifelse }ifelse cleartomark restore }ifelse currentdict/_Filters known{_Filters AGMIMG_flushfilters}if end end end }def /imageormask_l2_overprint { currentdict currentcmykcolor add add add 0 eq{ currentdict consumeimagedata }{ level3{ currentcmykcolor /AGMIMG_k xdf /AGMIMG_y xdf /AGMIMG_m xdf /AGMIMG_c xdf Operator/imagemask eq{ [/DeviceN[ AGMIMG_c 0 ne{/Cyan}if AGMIMG_m 0 ne{/Magenta}if AGMIMG_y 0 ne{/Yellow}if AGMIMG_k 0 ne{/Black}if ]/DeviceCMYK{}]setcolorspace AGMIMG_c 0 ne{AGMIMG_c}if AGMIMG_m 0 ne{AGMIMG_m}if AGMIMG_y 0 ne{AGMIMG_y}if AGMIMG_k 0 ne{AGMIMG_k}if setcolor }{ /Decode[Decode 0 get 255 mul Decode 1 get 255 mul]def [/Indexed [ /DeviceN[ AGMIMG_c 0 ne{/Cyan}if AGMIMG_m 0 ne{/Magenta}if AGMIMG_y 0 ne{/Yellow}if AGMIMG_k 0 ne{/Black}if ] /DeviceCMYK{ AGMIMG_k 0 eq{0}if AGMIMG_y 0 eq{0 exch}if AGMIMG_m 0 eq{0 3 1 roll}if AGMIMG_c 0 eq{0 4 1 roll}if } ] 255 { 255 div mark exch dup dup dup AGMIMG_k 0 ne{ /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec 4 1 roll pop pop pop counttomark 1 roll }{ pop }ifelse AGMIMG_y 0 ne{ /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec 4 2 roll pop pop pop counttomark 1 roll }{ pop }ifelse AGMIMG_m 0 ne{ /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec 4 3 roll pop pop pop counttomark 1 roll }{ pop }ifelse AGMIMG_c 0 ne{ /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec pop pop pop counttomark 1 roll }{ pop }ifelse counttomark 1 add -1 roll pop } ]setcolorspace }ifelse imageormask_sys }{ write_image_file{ currentcmykcolor 0 ne{ [/Separation/Black/DeviceGray{}]setcolorspace gsave /Black [{1 exch sub/sep_tint AGMCORE_gget mul}/exec cvx MappedCSA sep_proc_name cvx exch pop{4 1 roll pop pop pop 1 exch sub}/exec cvx] cvx modify_halftone_xfer Operator currentdict read_image_file grestore }if 0 ne{ [/Separation/Yellow/DeviceGray{}]setcolorspace gsave /Yellow [{1 exch sub/sep_tint AGMCORE_gget mul}/exec cvx MappedCSA sep_proc_name cvx exch pop{4 2 roll pop pop pop 1 exch sub}/exec cvx] cvx modify_halftone_xfer Operator currentdict read_image_file grestore }if 0 ne{ [/Separation/Magenta/DeviceGray{}]setcolorspace gsave /Magenta [{1 exch sub/sep_tint AGMCORE_gget mul}/exec cvx MappedCSA sep_proc_name cvx exch pop{4 3 roll pop pop pop 1 exch sub}/exec cvx] cvx modify_halftone_xfer Operator currentdict read_image_file grestore }if 0 ne{ [/Separation/Cyan/DeviceGray{}]setcolorspace gsave /Cyan [{1 exch sub/sep_tint AGMCORE_gget mul}/exec cvx MappedCSA sep_proc_name cvx exch pop{pop pop pop 1 exch sub}/exec cvx] cvx modify_halftone_xfer Operator currentdict read_image_file grestore }if close_image_file }{ imageormask }ifelse }ifelse }ifelse }def /indexed_imageormask { begin AGMIMG_init_common save mark currentdict AGMCORE_host_sep{ Operator/knockout eq{ /indexed_colorspace_dict AGMCORE_gget dup/CSA known{ /CSA get get_csa_by_name }{ /Names get }ifelse overprint_plate not{ knockout_unitsq }if }{ Indexed_DeviceN{ /devicen_colorspace_dict AGMCORE_gget dup/names_index known exch/Names get convert_to_process or{ indexed_image_lev2_sep }{ currentoverprint not{ knockout_unitsq }if currentdict consumeimagedata }ifelse }{ AGMCORE_is_cmyk_sep{ Operator/imagemask eq{ imageormask_sys }{ level2{ indexed_image_lev2_sep }{ indexed_image_lev1_sep }ifelse }ifelse }{ currentoverprint not{ knockout_unitsq }if currentdict consumeimagedata }ifelse }ifelse }ifelse }{ level2{ Indexed_DeviceN{ /indexed_colorspace_dict AGMCORE_gget begin }{ /indexed_colorspace_dict AGMCORE_gget dup null ne { begin currentdict/CSDBase known{CSDBase/CSD get_res/MappedCSA get}{CSA}ifelse get_csa_by_name 0 get/DeviceCMYK eq ps_level 3 ge and ps_version 3015.007 lt and AGMCORE_in_rip_sep and{ [/Indexed[/DeviceN[/Cyan/Magenta/Yellow/Black]/DeviceCMYK{}]HiVal Lookup] setcolorspace }if end } {pop}ifelse }ifelse imageormask Indexed_DeviceN{ end }if }{ Operator/imagemask eq{ imageormask }{ indexed_imageormask_lev1 }ifelse }ifelse }ifelse cleartomark restore currentdict/_Filters known{_Filters AGMIMG_flushfilters}if end }def /indexed_image_lev2_sep { /indexed_colorspace_dict AGMCORE_gget begin begin Indexed_DeviceN not{ currentcolorspace dup 1/DeviceGray put dup 3 currentcolorspace 2 get 1 add string 0 1 2 3 AGMCORE_get_ink_data 4 currentcolorspace 3 get length 1 sub { dup 4 idiv exch currentcolorspace 3 get exch get 255 exch sub 2 index 3 1 roll put }for put setcolorspace }if currentdict Operator/imagemask eq{ AGMIMG_&imagemask }{ use_mask{ process_mask AGMIMG_&image }{ AGMIMG_&image }ifelse }ifelse end end }def /OPIimage { dup type/dicttype ne{ 10 dict begin /DataSource xdf /ImageMatrix xdf /BitsPerComponent xdf /Height xdf /Width xdf /ImageType 1 def /Decode[0 1 def] currentdict end }if dup begin /NComponents 1 cdndf /MultipleDataSources false cdndf /SkipImageProc{false}cdndf /Decode[ 0 currentcolorspace 0 get/Indexed eq{ 2 BitsPerComponent exp 1 sub }{ 1 }ifelse ]cdndf /Operator/image cdndf end /sep_colorspace_dict AGMCORE_gget null eq{ imageormask }{ gsave dup begin invert_image_samples end sep_imageormask grestore }ifelse }def /cachemask_level2 { 3 dict begin /LZWEncode filter/WriteFilter xdf /readBuffer 256 string def /ReadFilter currentfile 0(%EndMask)/SubFileDecode filter /ASCII85Decode filter /RunLengthDecode filter def { ReadFilter readBuffer readstring exch WriteFilter exch writestring not{exit}if }loop WriteFilter closefile end }def /spot_alias { /mapto_sep_imageormask { dup type/dicttype ne{ 12 dict begin /ImageType 1 def /DataSource xdf /ImageMatrix xdf /BitsPerComponent xdf /Height xdf /Width xdf /MultipleDataSources false def }{ begin }ifelse /Decode[/customcolor_tint AGMCORE_gget 0]def /Operator/image def /SkipImageProc{false}def currentdict end sep_imageormask }bdf /customcolorimage { Adobe_AGM_Image/AGMIMG_colorAry xddf /customcolor_tint AGMCORE_gget << /Name AGMIMG_colorAry 4 get /CSA[/DeviceCMYK] /TintMethod/Subtractive /TintProc null /MappedCSA null /NComponents 4 /Components[AGMIMG_colorAry aload pop pop] >> setsepcolorspace mapto_sep_imageormask }ndf Adobe_AGM_Image/AGMIMG_&customcolorimage/customcolorimage load put /customcolorimage { Adobe_AGM_Image/AGMIMG_override false put current_spot_alias{dup 4 get map_alias}{false}ifelse { false set_spot_alias /customcolor_tint AGMCORE_gget exch setsepcolorspace pop mapto_sep_imageormask true set_spot_alias }{ //Adobe_AGM_Image/AGMIMG_&customcolorimage get exec }ifelse }bdf }def /snap_to_device { 6 dict begin matrix currentmatrix dup 0 get 0 eq 1 index 3 get 0 eq and 1 index 1 get 0 eq 2 index 2 get 0 eq and or exch pop { 1 1 dtransform 0 gt exch 0 gt/AGMIMG_xSign? exch def/AGMIMG_ySign? exch def 0 0 transform AGMIMG_ySign?{floor 0.1 sub}{ceiling 0.1 add}ifelse exch AGMIMG_xSign?{floor 0.1 sub}{ceiling 0.1 add}ifelse exch itransform/AGMIMG_llY exch def/AGMIMG_llX exch def 1 1 transform AGMIMG_ySign?{ceiling 0.1 add}{floor 0.1 sub}ifelse exch AGMIMG_xSign?{ceiling 0.1 add}{floor 0.1 sub}ifelse exch itransform/AGMIMG_urY exch def/AGMIMG_urX exch def [AGMIMG_urX AGMIMG_llX sub 0 0 AGMIMG_urY AGMIMG_llY sub AGMIMG_llX AGMIMG_llY]concat }{ }ifelse end }def level2 not{ /colorbuf { 0 1 2 index length 1 sub{ dup 2 index exch get 255 exch sub 2 index 3 1 roll put }for }def /tint_image_to_color { begin Width Height BitsPerComponent ImageMatrix /DataSource load end Adobe_AGM_Image begin /AGMIMG_mbuf 0 string def /AGMIMG_ybuf 0 string def /AGMIMG_kbuf 0 string def { colorbuf dup length AGMIMG_mbuf length ne { dup length dup dup /AGMIMG_mbuf exch string def /AGMIMG_ybuf exch string def /AGMIMG_kbuf exch string def }if dup AGMIMG_mbuf copy AGMIMG_ybuf copy AGMIMG_kbuf copy pop } addprocs {AGMIMG_mbuf}{AGMIMG_ybuf}{AGMIMG_kbuf}true 4 colorimage end }def /sep_imageormask_lev1 { begin MappedCSA 0 get dup/DeviceRGB eq exch/DeviceCMYK eq or has_color not and{ { 255 mul round cvi GrayLookup exch get }currenttransfer addprocs settransfer currentdict imageormask }{ /sep_colorspace_dict AGMCORE_gget/Components known{ MappedCSA 0 get/DeviceCMYK eq{ Components aload pop }{ 0 0 0 Components aload pop 1 exch sub }ifelse Adobe_AGM_Image/AGMIMG_k xddf Adobe_AGM_Image/AGMIMG_y xddf Adobe_AGM_Image/AGMIMG_m xddf Adobe_AGM_Image/AGMIMG_c xddf AGMIMG_y 0.0 eq AGMIMG_m 0.0 eq and AGMIMG_c 0.0 eq and{ {AGMIMG_k mul 1 exch sub}currenttransfer addprocs settransfer currentdict imageormask }{ currentcolortransfer {AGMIMG_k mul 1 exch sub}exch addprocs 4 1 roll {AGMIMG_y mul 1 exch sub}exch addprocs 4 1 roll {AGMIMG_m mul 1 exch sub}exch addprocs 4 1 roll {AGMIMG_c mul 1 exch sub}exch addprocs 4 1 roll setcolortransfer currentdict tint_image_to_color }ifelse }{ MappedCSA 0 get/DeviceGray eq{ {255 mul round cvi ColorLookup exch get 0 get}currenttransfer addprocs settransfer currentdict imageormask }{ MappedCSA 0 get/DeviceCMYK eq{ currentcolortransfer {255 mul round cvi ColorLookup exch get 3 get 1 exch sub}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 2 get 1 exch sub}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 1 get 1 exch sub}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 0 get 1 exch sub}exch addprocs 4 1 roll setcolortransfer currentdict tint_image_to_color }{ currentcolortransfer {pop 1}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 2 get}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 1 get}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 0 get}exch addprocs 4 1 roll setcolortransfer currentdict tint_image_to_color }ifelse }ifelse }ifelse }ifelse end }def /sep_image_lev1_sep { begin /sep_colorspace_dict AGMCORE_gget/Components known{ Components aload pop Adobe_AGM_Image/AGMIMG_k xddf Adobe_AGM_Image/AGMIMG_y xddf Adobe_AGM_Image/AGMIMG_m xddf Adobe_AGM_Image/AGMIMG_c xddf {AGMIMG_c mul 1 exch sub} {AGMIMG_m mul 1 exch sub} {AGMIMG_y mul 1 exch sub} {AGMIMG_k mul 1 exch sub} }{ {255 mul round cvi ColorLookup exch get 0 get 1 exch sub} {255 mul round cvi ColorLookup exch get 1 get 1 exch sub} {255 mul round cvi ColorLookup exch get 2 get 1 exch sub} {255 mul round cvi ColorLookup exch get 3 get 1 exch sub} }ifelse AGMCORE_get_ink_data currenttransfer addprocs settransfer currentdict imageormask_sys end }def /indexed_imageormask_lev1 { /indexed_colorspace_dict AGMCORE_gget begin begin currentdict MappedCSA 0 get dup/DeviceRGB eq exch/DeviceCMYK eq or has_color not and{ {HiVal mul round cvi GrayLookup exch get HiVal div}currenttransfer addprocs settransfer imageormask }{ MappedCSA 0 get/DeviceGray eq{ {HiVal mul round cvi Lookup exch get HiVal div}currenttransfer addprocs settransfer imageormask }{ MappedCSA 0 get/DeviceCMYK eq{ currentcolortransfer {4 mul HiVal mul round cvi 3 add Lookup exch get HiVal div 1 exch sub}exch addprocs 4 1 roll {4 mul HiVal mul round cvi 2 add Lookup exch get HiVal div 1 exch sub}exch addprocs 4 1 roll {4 mul HiVal mul round cvi 1 add Lookup exch get HiVal div 1 exch sub}exch addprocs 4 1 roll {4 mul HiVal mul round cvi Lookup exch get HiVal div 1 exch sub}exch addprocs 4 1 roll setcolortransfer tint_image_to_color }{ currentcolortransfer {pop 1}exch addprocs 4 1 roll {3 mul HiVal mul round cvi 2 add Lookup exch get HiVal div}exch addprocs 4 1 roll {3 mul HiVal mul round cvi 1 add Lookup exch get HiVal div}exch addprocs 4 1 roll {3 mul HiVal mul round cvi Lookup exch get HiVal div}exch addprocs 4 1 roll setcolortransfer tint_image_to_color }ifelse }ifelse }ifelse end end }def /indexed_image_lev1_sep { /indexed_colorspace_dict AGMCORE_gget begin begin {4 mul HiVal mul round cvi Lookup exch get HiVal div 1 exch sub} {4 mul HiVal mul round cvi 1 add Lookup exch get HiVal div 1 exch sub} {4 mul HiVal mul round cvi 2 add Lookup exch get HiVal div 1 exch sub} {4 mul HiVal mul round cvi 3 add Lookup exch get HiVal div 1 exch sub} AGMCORE_get_ink_data currenttransfer addprocs settransfer currentdict imageormask_sys end end }def }if end systemdict/setpacking known {setpacking}if %%EndResource currentdict Adobe_AGM_Utils eq {end} if %%EndProlog %%BeginSetup Adobe_AGM_Utils begin 2 2010 Adobe_AGM_Core/ds gx Adobe_CoolType_Core/ds get exec Adobe_AGM_Image/ds gx currentdict Adobe_AGM_Utils eq {end} if %%EndSetup %%Page: (Page 1) 1 %%EndPageComments %%BeginPageSetup %ADOBeginClientInjection: PageSetup Start "AI11EPS" %AI12_RMC_Transparency: Balance=75 RasterRes=300 GradRes=150 Text=0 Stroke=1 Clip=1 OP=0 %ADOEndClientInjection: PageSetup Start "AI11EPS" Adobe_AGM_Utils begin Adobe_AGM_Core/ps gx Adobe_AGM_Utils/capture_cpd gx Adobe_CoolType_Core/ps get exec Adobe_AGM_Image/ps gx %ADOBeginClientInjection: PageSetup End "AI11EPS" /currentdistillerparams where {pop currentdistillerparams /CoreDistVersion get 5000 lt} {true} ifelse { userdict /AI11_PDFMark5 /cleartomark load put userdict /AI11_ReadMetadata_PDFMark5 {flushfile cleartomark } bind put} { userdict /AI11_PDFMark5 /pdfmark load put userdict /AI11_ReadMetadata_PDFMark5 {/PUT pdfmark} bind put } ifelse [/NamespacePush AI11_PDFMark5 [/_objdef {ai_metadata_stream_123} /type /stream /OBJ AI11_PDFMark5 [{ai_metadata_stream_123} currentfile 0 (% &&end XMP packet marker&&) /SubFileDecode filter AI11_ReadMetadata_PDFMark5 application/postscript yawsskiss Adobe Illustrator CS3 2011-12-29T14:33:49+01:00 2011-12-29T14:33:50+01:00 2011-12-29T14:33:50+01:00 256 20 JPEG /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAFAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8Aj3nT8sfNflbUJ4rmymn0 9Gb0NRiRnheOvwszLUI1OqtnNZtNPGdxt3vtnZnbmn1cAYyAn1iTuD+n3hgc11JY3INwxawmJAbq YXO/T+Rid/v9jl44Rz46G04/a6LV6rN2XqzORM9LmlZ/oy61+Nx5i1b0mv7hogWFhacZL2eI/ETu Y4YyKjnJTbwFT2x02HwhxzG/IBHbHaJ1svy2nleMDjyTjvUedCuZ8upod69r6WW99CaxfT5HjMlt A8RhV44xtwBH8i1qetNyW6ubRTl6rBN7p7P9pdPiAwjHPHCMTwX/ABVZ+Z+O6m2pWgsVvedYGA6d QT1UjxGY50c/E4OruIe0OnOk/NG+HkR14u79Pu3RCyRtf2VkHHq30sUUJ3pxmYASf6tG5YMeknIk cuHmnVe0GnxQxyHqll4eGI50ep7q+/bvoPpt3PqF4YYoRHbxPxubqaRUVFB3IU/E5AFeK75fPQiE bnKnWaf2pyajKYYMEpxB+riqvM+k180VmuewdirsVdirsVdir6t/ILX9HvPy+0/TLeeMX+n+sl1a ch6ilpnkD8TuVYODXpXbtnQaDJE4wBzD5F7W6TLDWTySB4J1R6fSBXwp6Vma8u7FXYq7FWK/mX5j 0bRfJ2qnULlIZLm0ngtYSw9SWSSNkVUXqdzv4Zj6nJGMDfc7fsTRZc+phwAkRkCT0ABvd8ZZzT7c 7FXYq7FXYq7FXYq7FXYq7FXYq7FWX+UPyr85eZruBbfTprewkYerqE6GOJUr8TKX486DstcycOln M7DbvdL2j29pdLE8UwZ/zRub/R8X2RnSPijzD/nIHQNCk/KzzHfyadbNfRQI8V2YYzMreqgqslOQ O/jkRAXdbt35nJwcHFLg7rNfJ4j+UHkLSvP35Sa5p+nwm384aPderZ3XqOkcqzKrpHIAwX956ToW oCPh3ptkcmCEiDIXTk6XtPUYMcoYpcEZc62O39L6vt7+9GeXPyg8zeZfzLtDqnlGbyvoFtazQ6jI JEZDIYJIw8LAKj1ldaABvh3Zm64DhHCY97KPaUxnhmIBMO+6+9C2v/OMvmF/zRufL8gmXyfByvI9 XkjYwSKUBSKiNDV+ZCOqMDQE+GWVt597ijKOPcfuzKzEH7L36EgHdPLD/nEzX7PWNQuX1a3ubS2i K6NVXEkjMlP3iE0TgCQn7w/FQnYUNeWBlAxHMuVodXjxaiOSQkYQNiN77GwL9+523+KVeXP+cafz LuNbubjUY7PSrMRsqK8yyesxB4H9wJKFWPIk/LvlMtLeLguz3l2WHt0R7Q/NCPhxPOMeorryBs7+ /fmnb/8AOMfnoMeGoaWV7Ey3AP3CA/rzXfyZk7x+Pg9ePbjSdYZPlH/ilCT/AJxq/MFGKrPp0g/m WaWn/DRKcH8m5PJsHtroj0yfIf8AFMF85eTNZ8oauNK1b0/rLRLOjQsXQo5KggkL3QjpmLmwyxmi 7/s3tLFrMfiY74brfvSLKXYOxVTuLiG3iM0zcI1pyahNK7dslCBkaHNo1GohhgZzNRHVQtNdt/rM hgeSJ7YNIZwrIBwNGKv7e2WnBOIB73Bx9q4Mspw3qAJJMTw1E0d+qbWn5weY7aFTbeZdSRQPhgWe 4I3TmAFJ41oMyBjzg1Z+bqZ6vsmceIwgT3eHv9PFX093nSNt/wA9vOibL5j1D4i1Q5dyBGoZjuGp 1+/Jf4QP4vtaQeyJ88QHP+A/wizy/F7K99+eHneI+jceZL1X4+pwUurcQK1qqjw8cjCeeYsHb3t2 fT9k4JcM8ceLh4q4ZHb5Jbc/nJ5ouEf6x5k1SingYvXuByNA4HFTSu/fEwznr9rGOp7KgCfDiCDX 93vdA923Ot63Sa78y28srSzyzTyk0d3WRn2bh+2OR+LbbKfy8z/a7M9s6bGKHFQ7oEdeHlQv1bbX vfcURBPFPGJIiShJAJBXoadwMolExNF2mDPHLHijy9xH3qmRbnYqzbyt+T3nTzPo8er6XDA1nKzo jSyhGJQ8W2I8cysWjnONjk6HX+0el0uU48hPEO4XzTyP/nHD8xXWrGxjP8rTtX/hUYZaOzsnk4Ev bPRD+ef839qIj/5xm8/utWvNMjP8rTT1/wCFgYZIdm5O8fj4NcvbbRj+HIfhH/ikZD/zjB5rJHra tYIKfEU9Z6H2qiZIdmT7w0y9udP0hP7P1o2D/nFrUGp9Y8wwx/zenbM9PlWRK5IdlnrL7Gift3Dp iJ/zq/QUxt/+cWtOUf6T5gmkNN/Ttlj3+mSTJjssdZONP27n/DiA/wA6/wBATi0/5xn8iRENPeaj cH+UyRIvXwWLl+OWDs3H3lwsnttqzyjjHwP/ABSeWP5E/lhaEMdJNy4/annmf/hQ4T8MujocQ6OB l9qtfP8Aj4fcI/qtlGl+UPKuklW03R7O0kXpLFBGr/8ABgcvxy+OGEeQAdTn7R1Gb+8yTkPORr5J vljhuxVIfPX+FP8ACWpf4t4/4d9MfpHl6tPT5rSvo/vPtU+ziqSflB/yqz/Dk/8Ayrf0/wBD/WW+ s8PrHP6xxWvP61+++zxpXbwxVnOKuxV2KuxV2KuxV5r+Z/8Aypj9MWv+OqfpL6uPq3+9tfQ5tT/e X4ft8vtb5harwOIeJz+P6HqOw/5U8KX5T6OLf6OdD+d5Uw7/AKxU/wA/0xmN/gn44ndf83D+PBd/ 1ip/n+mMf8E/HEv/ADcP48FZL/0KfwPq8eG1eX6Xp126++Eflb2/3zDJ/L3D664fPwXJ/wBCn/Fw 49Tzp+l/td6++J/K/jiWH8vb1XPf+55+bl/6FO5njx58VrT9L1478fo60xP5X8cSI/y9e1XQ/wBR 5b18OdfFav8A0KX8PHh9puFP0v8AbqedPfrXCfyv44mMf5d2rh5mv7nnvxfHnfxte3/QqHxcqdPi r+l+nvkR+U/HE2S/l/e/j/c8mv8ArE70f2fR4/8Aa348afdSmH/Bb8/85j/r9wdOCv8Aaar7qpz/ APQp3pn1OPp035fpfjT6cR+Vvbn/AJyz/l7h9VcPn4NL/wDrFT/P9MYP8E/HE2f83D+PBd/1ip/n +mMf8E/HEv8AzcP48F3/AFip/n+mMf8ABPxxL/zcP48F6z+X/wDg/wDwvbf4Q/44XOT6v/f/AGuZ 9T/ej959uvXNhp+Dg9H0/jveQ7X/ADP5g/mf73a/p7tvp25Miy51jsVdirsVdirsVdirsVdir//Z uuid:D00C2737BC33E1118E74CC9C0FE11691 uuid:D10C2737BC33E1118E74CC9C0FE11691 uuid:CD0C2737BC33E1118E74CC9C0FE11691 uuid:1B986FB80533E111A40EAAA5319C4735 Print 250.000007 100.000012 Millimeters 1 False False SandRegular Sand Regular TrueType 3.5a3 False Sand Cyan Magenta Yellow Black Standardfärgrutegrupp 0 Vit RGB PROCESS 255 255 255 Svart RGB PROCESS 33 33 37 CMYK Röd RGB PROCESS 195 0 9 CMYK Gul RGB PROCESS 255 235 0 CMYK Grön RGB PROCESS 32 150 64 CMYK Cyan RGB PROCESS 0 163 231 CMYK Blå RGB PROCESS 46 34 129 CMYK Magenta RGB PROCESS 194 0 128 C=15 M=100 Y=90 K=10 RGB PROCESS 166 0 34 C=0 M=90 Y=85 K=0 RGB PROCESS 199 54 41 C=0 M=80 Y=95 K=0 RGB PROCESS 202 80 24 C=0 M=50 Y=100 K=0 RGB PROCESS 217 140 0 C=0 M=35 Y=85 K=0 RGB PROCESS 228 173 60 C=5 M=0 Y=90 K=0 RGB PROCESS 247 233 55 C=20 M=0 Y=100 K=0 RGB PROCESS 220 219 0 C=50 M=0 Y=100 K=0 RGB PROCESS 162 190 43 C=75 M=0 Y=100 K=0 RGB PROCESS 114 169 55 C=85 M=10 Y=100 K=10 RGB PROCESS 84 142 54 C=90 M=30 Y=95 K=30 RGB PROCESS 56 100 49 C=75 M=0 Y=75 K=0 RGB PROCESS 112 171 103 C=80 M=10 Y=45 K=0 RGB PROCESS 96 161 150 C=70 M=15 Y=0 K=0 RGB PROCESS 110 168 221 C=85 M=50 Y=0 K=0 RGB PROCESS 75 110 177 C=100 M=95 Y=5 K=0 RGB PROCESS 45 44 129 C=100 M=100 Y=25 K=25 RGB PROCESS 39 31 91 C=75 M=100 Y=0 K=0 RGB PROCESS 91 27 128 C=50 M=100 Y=0 K=0 RGB PROCESS 126 0 128 C=35 M=100 Y=35 K=10 RGB PROCESS 139 6 91 C=10 M=100 Y=50 K=0 RGB PROCESS 184 0 79 C=0 M=95 Y=20 K=0 RGB PROCESS 196 26 115 C=25 M=25 Y=40 K=0 RGB PROCESS 194 182 152 C=40 M=45 Y=50 K=5 RGB PROCESS 154 131 115 C=50 M=50 Y=60 K=25 RGB PROCESS 115 99 82 C=55 M=60 Y=65 K=40 RGB PROCESS 90 70 59 C=25 M=40 Y=65 K=0 RGB PROCESS 187 151 97 C=30 M=50 Y=75 K=10 RGB PROCESS 163 122 71 C=35 M=60 Y=80 K=25 RGB PROCESS 133 90 53 C=40 M=65 Y=90 K=35 RGB PROCESS 112 73 35 C=40 M=70 Y=100 K=50 RGB PROCESS 91 53 18 C=50 M=70 Y=80 K=70 RGB PROCESS 57 33 24 Färggrupp för utskrift 1 C=0 M=30 Y=70 K=0 RGB PROCESS 231 184 92 C=5 M=70 Y=90 K=0 RGB PROCESS 201 100 38 C=5 M=90 Y=75 K=0 RGB PROCESS 193 54 54 C=30 M=0 Y=95 K=0 RGB PROCESS 202 210 47 C=60 M=5 Y=95 K=0 RGB PROCESS 141 176 61 C=30 M=0 Y=10 K=0 RGB PROCESS 198 225 231 C=60 M=10 Y=5 K=0 RGB PROCESS 131 182 222 C=80 M=5 Y=10 K=0 RGB PROCESS 91 173 215 Gråskala 1 K=100 GRAY PROCESS 255 K=90 GRAY PROCESS 229 K=80 GRAY PROCESS 203 K=70 GRAY PROCESS 178 K=60 GRAY PROCESS 152 K=50 GRAY PROCESS 127 K=40 GRAY PROCESS 101 K=30 GRAY PROCESS 76 K=20 GRAY PROCESS 50 K=10 GRAY PROCESS 25 K=5 GRAY PROCESS 12 % &&end XMP packet marker&& [{ai_metadata_stream_123} <> /PUT AI11_PDFMark5 [/Document 1 dict begin /Metadata {ai_metadata_stream_123} def currentdict end /BDC AI11_PDFMark5 %ADOEndClientInjection: PageSetup End "AI11EPS" %%EndPageSetup 1 -1 scale 0 -39.9268 translate pgsv [1 0 0 1 0 0 ]ct gsave np gsave 0 0 mo 0 39.9268 li 549.418 39.9268 li 549.418 0 li cp clp [1 0 0 1 0 0 ]ct 12.165 15.6143 mo 4.45215 13.7251 -1.62256 8.99219 0.388672 0.00195313 cv 227.27 0 li 227.27 0 226.093 8.36182 227.589 11.7744 cv 230.278 17.9072 240.782 20.4937 276.448 20.4937 cv 312.091 20.4937 321.755 17.2632 324.268 11.3794 cv 325.775 7.84521 324.696 0.0517578 324.696 0.0517578 cv 548.992 0.00195313 li 548.992 0.00195313 551.626 9.33545 543.799 12.8169 cv 510.803 27.4902 382.747 28.7749 382.747 28.7749 cv 382.035 38.0986 li 162.088 38.1396 li 160.123 28.1255 li 160.123 28.1255 63.3408 28.146 12.165 15.6143 cv cp false sop /0 [/DeviceCMYK] /CSA add_res 0 0.972549 0.956863 0 cmyk f 53.2446 19.8013 mo 57.3481 20.3511 li 59.0435 23.0034 li 50.7559 22.0864 li 53.2446 19.8013 li cp f 20.8403 5.41211 mo 21.0703 5.84521 31.2139 19.1274 32.3408 20.6523 cv 33.3906 22.0742 31.3271 37.3901 32.0205 38.4116 cv 32.7134 39.4336 38.1333 39.6055 39.5186 38.9131 cv 40.9033 38.2212 43.9287 35.4443 42.9824 33.3696 cv 42.0361 31.2949 38.6689 23.5186 39.2666 22.0381 cv 39.8643 20.5581 41.8315 18.3101 42.1201 17.9404 cv 42.4824 17.4771 53.2041 2.89307 53.8965 2.89307 cv 54.5884 2.89307 55.5366 2.20068 55.5366 2.20068 cv 55.5366 2.20068 56.0171 1.18604 54.9878 1.18604 cv 53.958 1.18604 50.2778 1.51709 49.2388 2.20264 cv 48.1997 2.8877 43.2363 10.7051 43.2363 10.7051 cv 39.5425 15.9194 li 39.5425 15.9194 37.5874 17.4854 37.0215 17.2261 cv 35.7188 16.6284 28.4609 7.73096 28.4609 7.73096 cv 28.4609 7.73096 22.6802 1.29932 21.6836 1.25781 cv 20.6865 1.2168 20.4941 4.76318 20.8403 5.41211 cv cp 0 0 0 0 cmyk ef 0.25 lw 0 lc 0 lj 4 ml [] 0 dsh true sadj 20.8403 5.41211 mo 21.0703 5.84521 31.2139 19.1274 32.3408 20.6523 cv 33.3906 22.0742 31.3271 37.3901 32.0205 38.4116 cv 32.7134 39.4336 38.1333 39.6055 39.5186 38.9131 cv 40.9033 38.2212 43.9287 35.4443 42.9824 33.3696 cv 42.0361 31.2949 38.6689 23.5186 39.2666 22.0381 cv 39.8643 20.5581 41.8315 18.3101 42.1201 17.9404 cv 42.4824 17.4771 53.2041 2.89307 53.8965 2.89307 cv 54.5884 2.89307 55.5366 2.20068 55.5366 2.20068 cv 55.5366 2.20068 56.0171 1.18604 54.9878 1.18604 cv 53.958 1.18604 50.2778 1.51709 49.2388 2.20264 cv 48.1997 2.8877 43.2363 10.7051 43.2363 10.7051 cv 39.5425 15.9194 li 39.5425 15.9194 37.5874 17.4854 37.0215 17.2261 cv 35.7188 16.6284 28.4609 7.73096 28.4609 7.73096 cv 28.4609 7.73096 22.6802 1.29932 21.6836 1.25781 cv 20.6865 1.2168 20.4941 4.76318 20.8403 5.41211 cv cp @ 59.627 20.2129 mo 59.627 20.2129 60.4902 16.5889 59.793 15.5537 cv 59.0957 14.5181 57.1704 14.6416 56.2432 14.9541 cv 54.7822 15.4468 53.8965 15.7837 53.8965 15.7837 cv 53.8965 15.7837 52.5879 16.165 51.394 15.9741 cv 50.4272 15.8198 50.4927 14.3975 50.6392 13.9287 cv 50.7881 13.4546 53.2031 11.5278 54.8574 11.0864 cv 58.0093 10.2451 60.0215 10.4854 61.7842 11.1758 cv 63.5469 11.8662 64.5542 12.876 65.2476 14.9541 cv 65.9404 17.0322 65.6709 25.9419 65.0112 27.6592 cv 64.4624 29.0898 62.2075 31.4858 58.5391 31.4858 cv 55.7373 31.4858 52.8608 30.2905 51.1245 28.7139 cv 49.6133 27.3418 47.748 25.2393 47.438 23.3384 cv 47.1953 21.8477 47.9316 20.5371 49.0464 20.0737 cv 50.8169 19.3369 54.9531 19.2974 57.0303 19.7095 cv 59.627 20.2129 li cp ef 59.627 20.2129 mo 59.627 20.2129 60.4902 16.5889 59.793 15.5537 cv 59.0957 14.5181 57.1704 14.6416 56.2432 14.9541 cv 54.7822 15.4468 53.8965 15.7837 53.8965 15.7837 cv 53.8965 15.7837 52.5879 16.165 51.394 15.9741 cv 50.4272 15.8198 50.4927 14.3975 50.6392 13.9287 cv 50.7881 13.4546 53.2031 11.5278 54.8574 11.0864 cv 58.0093 10.2451 60.0215 10.4854 61.7842 11.1758 cv 63.5469 11.8662 64.5542 12.876 65.2476 14.9541 cv 65.9404 17.0322 65.6709 25.9419 65.0112 27.6592 cv 64.4624 29.0898 62.2075 31.4858 58.5391 31.4858 cv 55.7373 31.4858 52.8608 30.2905 51.1245 28.7139 cv 49.6133 27.3418 47.748 25.2393 47.438 23.3384 cv 47.1953 21.8477 47.9316 20.5371 49.0464 20.0737 cv 50.8169 19.3369 54.9531 19.2974 57.0303 19.7095 cv 59.627 20.2129 li cp @ 78.8301 21.7856 mo 80.228 21.7856 83.2163 12.5791 83.855 12.311 cv 84.5488 12.021 85.7271 11.7407 86.4517 12.0879 cv 87.4395 12.5615 90.3711 21.4424 91.0854 21.7603 cv 91.8496 22.1001 93.7749 17.1299 94.7642 15.938 cv 95.6606 14.8564 100.892 10.0098 101.29 10.0098 cv 101.692 10.0098 101.626 10.374 101.626 11.0693 cv 101.626 11.7651 100.998 19.708 99.6123 22.1328 cv 98.2261 24.5576 94.812 28.4321 92.1709 28.7139 cv 90.8604 28.853 87.144 23.1719 86.6904 21.7856 cv 86.4019 20.9033 85.0679 21.0957 84.5869 21.7856 cv 84.2778 22.2324 80.1577 31.3843 78.8301 31.8789 cv 77.6074 32.3359 76.0239 32.4131 75.6665 31.7827 cv 75.313 31.1523 68.9629 18.1533 68.4409 16.2456 cv 68.0752 14.9097 68.0938 11.7427 68.4409 11.3955 cv 68.7876 11.0488 69.1313 10.0146 70.1719 10.3604 cv 72.3091 11.0693 78.2773 21.7856 78.8301 21.7856 cv cp ef 78.8301 21.7856 mo 80.228 21.7856 83.2163 12.5791 83.855 12.311 cv 84.5488 12.021 85.7271 11.7407 86.4517 12.0879 cv 87.4395 12.5615 90.3711 21.4424 91.0854 21.7603 cv 91.8496 22.1001 93.7749 17.1299 94.7642 15.938 cv 95.6606 14.8564 100.892 10.0098 101.29 10.0098 cv 101.692 10.0098 101.626 10.374 101.626 11.0693 cv 101.626 11.7651 100.998 19.708 99.6123 22.1328 cv 98.2261 24.5576 94.812 28.4321 92.1709 28.7139 cv 90.8604 28.853 87.144 23.1719 86.6904 21.7856 cv 86.4019 20.9033 85.0679 21.0957 84.5869 21.7856 cv 84.2778 22.2324 80.1577 31.3843 78.8301 31.8789 cv 77.6074 32.3359 76.0239 32.4131 75.6665 31.7827 cv 75.313 31.1523 68.9629 18.1533 68.4409 16.2456 cv 68.0752 14.9097 68.0938 11.7427 68.4409 11.3955 cv 68.7876 11.0488 69.1313 10.0146 70.1719 10.3604 cv 72.3091 11.0693 78.2773 21.7856 78.8301 21.7856 cv cp @ 102.76 29.3457 mo 102.76 29.3457 108.476 30.3042 110.554 29.6118 cv 112.632 28.9199 116.681 26.6357 116.86 24.1299 cv 116.977 22.4897 116.238 21.3599 114.851 20.4033 cv 113.576 19.5225 110.454 17.8735 110.454 16.1563 cv 110.454 14.9316 112.302 14.042 113.339 14.042 cv 114.376 14.042 115.542 14.6997 117.623 13.0479 cv 119.7 11.3955 119.315 10.6621 119.315 10.3359 cv 119.315 10.0098 119.007 9.31934 118.314 9.31934 cv 117.623 9.31934 112.774 9.31934 110.344 10.0098 cv 107.806 10.731 104.474 11.7925 104.46 14.8599 cv 104.447 17.9268 109.8 20.6714 110.451 22.3525 cv 110.962 23.6714 108.946 25.1245 107.232 26.3779 cv 105.729 27.4756 104.807 27.6162 103.768 28.2827 cv 102.729 28.9492 102.76 29.3457 102.76 29.3457 cv cp ef 102.76 29.3457 mo 102.76 29.3457 108.476 30.3042 110.554 29.6118 cv 112.632 28.9199 116.681 26.6357 116.86 24.1299 cv 116.977 22.4897 116.238 21.3599 114.851 20.4033 cv 113.576 19.5225 110.454 17.8735 110.454 16.1563 cv 110.454 14.9316 112.302 14.042 113.339 14.042 cv 114.376 14.042 115.542 14.6997 117.623 13.0479 cv 119.7 11.3955 119.315 10.6621 119.315 10.3359 cv 119.315 10.0098 119.007 9.31934 118.314 9.31934 cv 117.623 9.31934 112.774 9.31934 110.344 10.0098 cv 107.806 10.731 104.474 11.7925 104.46 14.8599 cv 104.447 17.9268 109.8 20.6714 110.451 22.3525 cv 110.962 23.6714 108.946 25.1245 107.232 26.3779 cv 105.729 27.4756 104.807 27.6162 103.768 28.2827 cv 102.729 28.9492 102.76 29.3457 102.76 29.3457 cv cp @ 0.945098 0.823529 0.815686 0.898039 cmyk %ADOBeginSubsetFont: SandRegular Initial %ADOt1write: (1.0.24) %%Copyright: Copyright 2011 Adobe System Incorporated. All rights reserved. 12 dict dup begin /FontType 1 def /FontName /SandRegular def /FontInfo 5 dict dup begin /ItalicAngle 0 def /FSType 0 def end def /PaintType 0 def /FontMatrix [0.001 0 0 0.001 0 0] def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 32 /space put dup 97 /a put dup 98 /b put dup 101 /e put dup 104 /h put dup 110 /n put dup 111 /o put dup 114 /r put dup 115 /s put dup 116 /t put dup 118 /v put dup 119 /w put dup 121 /y put def /FontBBox {-500 -656 1577 1123} def end systemdict begin dup /Private 7 dict dup begin /|- {def} def /| {put} def /BlueValues [0 0] def /password 5839 def /MinFeature {16 16} def /OtherSubrs[{}{}{}{systemdict/internaldict known not{pop 3}{1183615869 systemdict/internaldict get exec dup/startlock known{/startlock get exec}{dup /strtlck known{/strtlck get exec}{pop 3}ifelse}ifelse}ifelse}executeonly]def /Subrs 5 array dup 0 <1C60D8A8CC31FE2BF6E07AA3E541E2> | dup 1 <1C60D8A8C9C3D06D9E> | dup 2 <1C60D8A8C9C202D79A> | dup 3 <1C60D8A849> | dup 4 <1C60D8A8CC3674F41144B13B77> | def put dup /CharStrings 14 dict dup begin /.notdef <1C60D8A8C9B7A73DB6FA4686837C192F1BB0E9598152E4DA354EE7 986E29CE5EDDEE641BAA9040DD77E8E7DEBADE6F14651D81F4D3B5D1109C2C8A 0787C3C8F04AC11A8E71E40859ABEF28036A0A90C3C814BD98FA68493FF0C079 AF7641A2AC8A5FB41E93607D1B9CB3135424A37783277080C07E8028AD16EA26 C4C26ABCB5C51345979678115BC95094D92C787DE8CD0881A9CBAD8B02377F11 DF4D2354E4E9DF4CD655C04C0BE8F1969D5082C482C017D3FE4FB4FDDA573781 A20CCA9444C9197858596417C68EAEDD1CAB7BA5415D69968E5852EF84DBD6F1 055E62DDA0246555BDB5C3708955081FFE3D63CB7126F9DDD31FB14E8A257B4F E9803D255A1C9B95D4D4575616BCB15C6A6204B3B6CBF9F3B142458F98429623 4E2A8DE1567D46A244C3B12050E722E67890827A06DC0876D87339224787DDF7 45A61376900932D29A5B01E6B26EFEC9C6453E38B6FCF8C605AAE626762751EF C4DDD03D199E89C04183A73E1EFA0C76359F81897596F176A6677468C4D1C185 3E0E4EF8B7279D3C384721F3BACEC71B2DA0AA63346D8DB00E70CB15CB7EC8A1 BE1693A7592BB78F0512C45D0DDEA7D362A19019078925A01A> |- /space <1C60D8A8C9B71A73C3> |- /a <1C60D8A8C9B64EDFFBBAD176F3BF313FCED610B3015EB124CD5B5B7921FC FB9CA678E4F149AEFFD40620EA37C7313E083756B78E4A8AED62137A05F11A2B 3E47803788CC674020BB6C900640138B7E4D8453B2614C3ED938EAAE6D0E732F D1F5C8BCC93C008725245D2FA624380443AFD4D0DD93D318E245A8BF8F4800A3 988D810E8DE5C06C4E350A67512141B406B408FCE1BE4C5D5E257375755F0AB2 CD4CD9AF24D03436A130445A5CF579735C3777EAB41BB5D67B78E9F611041091 DB76AC45B8C12BD22FF1CB96AC3D46834660068ECC09B627D4757F645E4A034F 9D9EB3D890C5CC1FC0A1DC870F7A00373A354E886CB3DEB06369F15A87197BD1 EBA3FF41228418452D440BE7C470F4890F49782A67D1647F9821D924A5BD8F9B 19E56599CB122AF429994A5F9013B991CB5A4F6A43CCA1334D78E86681FD7A63 FCB16F9589E20D32AD7D6094CCDFAD732FC4A4DB4C28B5B2CAD644019A505567 D1A79B9D3C949DB63AE484DA0E3FF7CEA3DDB4AAFE3F718CB03E9E51DC7DA290 CA6296BC83F2C2819E2F2A4EC06DED3051B03627DBE8CABC654875142F8B8EFF 73720FA7DE81F33D487A6BDCF792EF060F1A97CD7E4558E3410A5C> |- /b <1C60D8A8C9B64EDFFBB749431CD60BCB6223CF07470ACEFB1F1898BB068F 0E2E00232C49E9930AF362F48A80D4F21FAE884937A63DC3D11786C75A71FB2F FC369D94F23626DC98309E20CF9A5321269497B12F20E131179D7D9B5E1F9E01 F9C82C134A5AE200DE5A9B4D0CE446C2C7564BF28AE2276AF529C8249EB6760C 480DA56375BECA6FE3C32FABE9329C906C57D336716FC219844B5DD1389ECDB3 ADC6C9340B1B250D92FAD5C8672113B1C62E50439BACCEC0D5A3B6483AC14323 0F28C040DB2B20A91FF060718391A4721DC2ABD4CFCC35E5D387F33D6B57E087 C06423F1930A6B79EFF1A3122CF0E44C93317E1A8B97ACD0BA8CDDC26D285FAA DE75756820F57CED896DE406E188C1ED9F39CE6CE788CB25138D3ABDDC58EC85 1C50701B4DBED182380893737A5721A68CD1525C9D30F2EA455C64BFED25FD5C E11CC4A54B20C2E5A053205600251B0967A79265334E0ADD9C0DDEA1B8CD0C06 698A7384FDBE422800413E078A212253FF56B3CA16BF0F73CEC53BF1AF5F870A 6CE3C2BCF7E472BF2AD55900CF9DE7ED44282EF7B35005357914127B5BB68232 BE36CD9F7D928003E548CE49963493B1D18E49AC7C088312E9EEF13197A27F54 556F7BA22F09F80C0700690303B5826B5A37CEA9C67BE1F36DDB06AF87B7122D 13FA8E29> |- /e <1C60D8A8C9B64EDFFABCD3BAFF1C5E384810611B789B4844DFC516CE954C 709CAA82011C5D4ACF28C916C800923CD920CF0870DEC6E465EECDBE7A94CAE3 E43C62FD402CA8E69FEEC6BA6C375DF9E40E11FD0D44A853C5AE24B4073D8DCC 2E9AC900FE84C088C3FA8A42ACF48008B53E605F75529A9853ADD93356DC5B06 8F286CEC59D120E066A0A3EF7DFC7986CA75A6FF033E92D9BD86091AAD0378E9 8FA942E8C17747AA58BC6D80275E4E025F43277422588AF6067098923F763FBD 204C565171E14D30270DFBCFF2BDE4FC630935A8E27FA78A8C05B87318413964 26A46F14700C43E92FB2B049A2656DFD33D12CD3652FCF08BAC1E92619250425 7E9B10E575DF07ADD1FE0F8FA0BF6ED5117C4F8944EE433BB916DCE18BEE0633 2D1223CFA89AE737D0788FC09572446C2B07A6F81AFAD8D3FC966115B4D7426E 1C71DDB4CD245C3D28BF4A848DF7301B507F597278B37D08F1383CAB213ADB08 7113C3EA31F960D9D6625BA2F031A3D9DB0C0741FD3E3F7CAC6C531C29441133 EADC> |- /h <1C60D8A8C9B64EDFFBC62EF76620EFC3E7E2B931C729BA4FDD57073EA295 FBB09433698917FDB5EED3D33018539AF207F8DE4BEBB161EA415562AD81CCA6 476CCB2AAD5A13F2390BC61661E577CD31A5ECA6D07FB61108CF527644202772 57C4A7680D8DE85426FA2EF8A455FDAD5EFCCEEADCB1205AFE383C3752D17BFC 84542DCC2D1864513ADD959A22E5F988FC4C73C77F3E08835D7BD136421BDE14 904E4369E1114490A3E5C5869AA837301708CDC5D7FB2A2BDD039B1149E24DE5 23B00AB6189A20440ED27B72E54813F4D07474728C613811DC3EC1E3765D8BA6 309F47F63DF933AC8FD2E4613C5B4C5B57C283CD21FB4A9D3FE5A2F3B7210C37 6E90E17FB64AC0FE373517FCF218AF1885C1C178B6B8311670F8426CB6A4110C C0449D52A48CFAAA13A19266D6166AAED8127F0236E0BE3A929D8906C810C33B 985FC6211559269D5B389102911B63D779CC78ED43E949066DD97567F4A946E8 7F52A9EB0A7BFDA14A2D2E50FF9F57CA4C5AD2D5EFE7B916D7EAD8C194F2A9CF 5DB924D7A336681D7C49C43E91D373D279AC13B84E7681> |- /n <1C60D8A8C9B64EDFFBA98358B758F524F5F8918467727F0AF71AFD650893 CD2AA0958D936DEBE57F9B02575672637EE3156E967F82455D4355E584B68619 69B16EC16B13C4F51F6120BEC0F6196ECFD4E68017270A760F2D90311B4F26B8 20839DBC8067E0A700E1ABE7C890B4DBAB60207B05CCE073D18948EF9597930F 0ECBE815014F8033F29E14C528BEDED0F60638C86AC6A0771CA6082CCD641945 3ADC59F2B6AF8C6F6CF76B42505170BC1C752B0918B102451639518F90235CE5 ADAD9F0725AA7092D78157AE87368B1D14FB1A6CB5F7EBC25B8A34842B2F12CB 508E5E51D9F96754E90C6366E111DD8C57A2CE3AB9BB95CE4E769D70A7F912C9 0ADE4FB73ED29671E422A6718ECD6BC592792301618409F907B98F382776D2D5 F4D0EC15146BC95ED20D1D389E2CDD4C84BB91366B455969EE8AF4652A716FA5 AA1EDF15EBFAB1ABE9A5CEC1D3C05CDE6A479C22EB14E8E496C57B885453133A 29724F0880DD1F264C748CC3C98FE8D558362770F0F4E254848351> |- /o <1C60D8A8C9B64EDFFBB5D6ECF46199649CE94D85CEC8474552129646310D 795C79FE630867B03A3DCC87DAB37382ADA7530508E5E0EC978D73664F75C1A7 C172A7AE0F470DCC487094082BB682EABAA5FECF7AEEE1CCFA80FF8E3C7FD369 4446FE6C4EE23FCAB63D709C1434240E565415337EDA1BBB1342A2C41A55B148 2D9FBEC990D7005ADF9AA73EF33A2941A4D8D179521716BAA6D4BF495C9E9404 61808497F47D01509BFBDB792841C2598F4225A7AFDA566A5150925A341AF48A B9A350DA54F7DF38698ED25F2E9E1B930E623F138E73B23975CD2E6BAAC18907 D413C2ACC8916DC5BA278941F87142EBA2571D48622F7E124933A1097848C1F8 F5DC4DACE3FB8AFA9402124EDDDA40FC5B7374C88B6906133F18B9D780F5282C 0A> |- /r <1C60D8A8C9B7A73DB6C142F53CEC83B6CB905D3DC693B0B669360AA8B825 E2FCE33E8AC840AD0B444FDD384AD5A2E8F998878F16D27C1BC0C9A1C8B50627 3EE2DBE0712135B9158D09A679FAE96631CBE98CF75C7901DA58078504FC9E37 94525072B4D6F4A2BFFD33BA041A9622C5C700BFD4CE8642CBAA4371D0CCD2C8 277EB08468BA749688170BC086BAF7ED7ACFB6890501BFC07D31557A59A12C53 D1074DF04F847B4C3A53BD10EAA86FFC248817FCDE9DD3E806B2E2D6DA782FED FDB06C47CC4560770271693CDEACB957D41F12DAA3BBE0B8613E9667EDC364E7 3D974DC2576A1CE2BFFE5586C33881BDF2D0B1C91732151248D91A637AA5B9A6 005AF2DED14BE91D29770C6E2E8322A7D80206CA342A99B8FB578E700057EEFA> |- /s <1C60D8A8C9B7A73DB6C4DE78399FDB86A6CF7894FA5170A1CA6E1C786F37 112796D5B83A6498C7C1849C431C5D17850ED7EF90DCCB2B92122B0517A8A3EE A8C3CBCE673E270FB3C46262833D90771704EEA0F7172EDF5F202F326CC5F72C 7F938708529612E09F71CC46EC16B198E0B76E1870A22117539395FF22701F81 0E9E22D83FC3A0B07CAB8268582CE8F6AE32F7BF6EA4DEBCE0A59B2911D85FD2 99280F6D473BA13578AC1E79DEF15F990A7B687F7A0EECA1921DFD20F0E88354 F2B2DB54792ABC8379A3D278037E3F28036537A81632105E0C373E35C2119642 8AE37C79C1F2CC92C5F284BD63A916166D1A56633D6D53C51ACACA9779E2DE68 3EF785F8327CE6B85B6CB2A1D8D80BF47B04D1300C653D2B905207> |- /t <1C60D8A8C9B7A73DB6C769B20054F8700E8A9FA6C6CF245359BDE785455D AEAA345786E52790932F7FC16F21D88F167E478F345150774F508B9F3EBECA7A 282E56E9634FD6BA71CC1F9D2943E995F15AE19B911EED8AAD4E20DEA7FACAEE 874E988B974EFEDD956BD84331AF33F3B998D04096D81DE455640DB54A2C0F6F 53109BAFC89254092BD1D038BAEF6283A549946CA2A56377EAE7B146C6CC65D0 309E88D286CD4AB5A10C26794A6390AB4C90F0D5F36BD2F2FAA655699733FBCE 0E662174F1A4ED095B0045AFEE2DEC363BB3C9A056EEBF43252970AC6ED2A1EA 2855F93097A94308A837FF2FBDF1BE0767A224B062B781B2A902EFAF0BDE272B 616A142F0D7C1AFCBFCA2C61AC3227E188B430016887F21E21B378DA5BAC6FAB FFFAD390F00BA9E6E75223F7935A3F178505FE547719290991294D9217F83C4B AB6A6C4BBF47D6975D7A932350E74E865A8E946D4A661ED74E44563D4E2AE84B B6737C3BDD2CE4E1E4795A620E6040E53F6743DB76B9815BC8B979B5322560A2 6248AC19EA83B6C153C9A9> |- /v <1C60D8A8C9B64EDFFABBA438943F04C103F3AF0CA89C9D7922E821A5D217 F1877A86B8E99F2D288EEAB8EC00E8469FFEEA7A87230B99E6EDF1856A8833C0 AA5D75234C03A5CEF10F8DA371AC1DC988A3185C3E4F6A80571BACDE80DC0484 CD4B034D7433FB39AB31E40454A952CE53EF1291F8F7E6394711CD840FEBF1C2 BF404AE2DD8ED6562B5A48F8E251E60C6CDEF9BEB11F6577A3B78B209C49834F 88EE68077CD1EFFF308F6F27FF90EE367D8FBEC9B4958F3ED585EAE9B607D251 BC3AED2A82BF292912511380917DAFBBB94033CA8BC1485BDFBB1AFC2F6F36C9 BAABB9C6E7C55CC0C65703FCAC11B2260466C4872BDFDF296E26F4427AF69AAC 4CCC6B5FBF709EE26829449675B50118C12F4BF7D97861A2A80667E92E8349F2 7A00C49052F3D798732566A20E10870FBF926BE7F3AC79EE00173BF6D146C2E7 7EC7D3363B6D2D73799AEF6B8E26E72E806B83> |- /w <1C60D8A8C9B5EE3100C9C4565CED010F9776483003E773B98F6426B18A8C 0EB57FF6C89475261DEB7D253F7E6D821071A17F2C2F43A8420D6481FCA6DA69 8E4B31FE18F0353DE27F68E429138C11911A81315D48B0DEB0030CCDECC72C95 A578CC1591AF74948F2C8FB9C918785D57D3F412A6B38D794C3BF48A5BD6A9BA BE008A7367F5D344BEC9893836FE57AD61AB6865A171133D32659859CF127459 CD33BB5DE6AE18AE04E9150B7B2D3D789C8FB795AD226DF34D3D07CF7AA26333 E9DD3E19CDE90D9B23DE34FBE636720F3203994BC04260DB65F1FEB529A984E7 40C2D4D195679F694BA781982C1BBA440A38A8FECB6C8571C0C7446A92347FF6 22779F90BBA95D0EF8F4D8A74A1D40754144509F0A89976AE653EC873C464A7B 2479188E9E118FB3B26F9E21C8D69CBC04B9310EFC57335FB5C1F7E1240345E5 DA200163CC346C3A606B9CADA1694CE5A25F847C21A3092F44097958B41818B9 E82C8D437E8BBD6E0DC26E764FBA7DD1EFE6EB9AA77B226244CF2D2624E3BFA8 D61F0EB012172565CE13366812EB95607F9022F319A410D81776C22DE849FD41 07F985F45AF0C8FF09B0FF9C53A66735478342DFA7F71056EB21851371D20E5A EBB2BE896C62BC98056601E7E4DC7C49AC3CD0B1B61C55F80BCD691702815392 D62C954B5EB586DD30A4BFE879> |- /y <1C60D8A8C9B64EDFFBAABA1D6D9F6A70E357D51CFC85AEC480C38824D9A3 9D1C0E884198EF635FF6ECF8BB284AF37F5BE393711D6C09D4F28688B514CC92 4354A04F03514EF4C7E9510ECEF87B10A0DF8C67DFDEFF09A3B23B0E667C152F 4EC09CE48E8532FC65DC32B2772621E2A26B7DD6280DD12D4830687174DB15A0 B71E00CBF73E15E58DBA17AC29AFE9F0216DB8A112EE5CCAF9DD085B5B946CF3 7B3B5E8A5A2B37AD53E9BB0778499AD054456911B03A608068E291319145C6F6 6BF18A186F2F7BB407AFA9613855559DC9D0A60EBD9B42DFF3EA6C84A2120CE7 D328D7B6B536028C02AB2DD2B364FC75A7E34B5CBD07CE2658F74950822A9FDD 0BB1DEF292A54920DAE9FAA297AD1D637D7BD84B8EDA94FB40BB9DABD605B932 8444A6295F8D0A7C2F81EB538191ABFB8BEE289D7C2DDEDB81798F6A34C8E456 772E680BEB3478404E0A06B0712A56D56324A69F48EB4607D4383D60DD4161C1 50D976E2F66BE607C9D7906DE1D61D2501FBD729F1FE0649F9C6196DCFE57AD2 471AAA4394A0677B2B52822C4613642F7F10056B5E6FFD04AC> |- end put end dup /FontName get exch definefont pop end %ADOEndSubsetFont /UGSOPT+SandRegular /SandRegular findfont ct_VMDictPut /UGSOPT+SandRegular*1 [32{/.notdef}rp /space 64{/.notdef}rp /a /b 2{/.notdef}rp /e 2{/.notdef}rp /h 5{/.notdef}rp /n /o 2{/.notdef}rp /r /s /t /.notdef /v /w /.notdef /y 134{/.notdef}rp] UGSOPT+SandRegular nf UGSOPT+SandRegular*1 [8.793 0 0 -8.793 0 0 ]msf 218.186 34.1606 mo (yet another webserver) [5.86035 5.86084 4.39648 3.66211 5.86084 5.86035 5.86084 4.39648 5.86035 5.86084 4.39648 3.66211 8.79297 5.86035 5.86084 4.39648 5.86035 4.39648 5.86084 5.86035 0 ]xsh 20.1074 4.82568 mo 20.3379 5.25879 30.4814 18.541 31.6084 20.0659 cv 32.6582 21.4878 30.5947 36.8037 31.2881 37.8252 cv 31.981 38.8472 37.4009 39.019 38.7861 38.3267 cv 40.1709 37.6348 43.1963 34.8579 42.25 32.7832 cv 41.3037 30.7085 37.9365 22.9321 38.5342 21.4517 cv 39.1318 19.9717 41.0991 17.7231 41.3877 17.354 cv 41.75 16.8906 52.4717 2.30664 53.1641 2.30664 cv 53.856 2.30664 54.8037 1.61426 54.8037 1.61426 cv 54.8037 1.61426 55.2847 0.599609 54.2554 0.599609 cv 53.2256 0.599609 49.5454 0.930664 48.5063 1.61621 cv 47.4673 2.30127 42.5039 10.1187 42.5039 10.1187 cv 38.8101 15.333 li 38.8101 15.333 36.8545 16.8989 36.2891 16.6396 cv 34.9863 16.042 27.7285 7.14453 27.7285 7.14453 cv 27.7285 7.14453 21.9478 0.712891 20.9512 0.671387 cv 19.9541 0.630371 19.7617 4.17676 20.1074 4.82568 cv cp 0.831372 0.658823 0.576471 0.698039 cmyk ef 20.1074 4.82568 mo 20.3379 5.25879 30.4814 18.541 31.6084 20.0659 cv 32.6582 21.4878 30.5947 36.8037 31.2881 37.8252 cv 31.981 38.8472 37.4009 39.019 38.7861 38.3267 cv 40.1709 37.6348 43.1963 34.8579 42.25 32.7832 cv 41.3037 30.7085 37.9365 22.9321 38.5342 21.4517 cv 39.1318 19.9717 41.0991 17.7231 41.3877 17.354 cv 41.75 16.8906 52.4717 2.30664 53.1641 2.30664 cv 53.856 2.30664 54.8037 1.61426 54.8037 1.61426 cv 54.8037 1.61426 55.2847 0.599609 54.2554 0.599609 cv 53.2256 0.599609 49.5454 0.930664 48.5063 1.61621 cv 47.4673 2.30127 42.5039 10.1187 42.5039 10.1187 cv 38.8101 15.333 li 38.8101 15.333 36.8545 16.8989 36.2891 16.6396 cv 34.9863 16.042 27.7285 7.14453 27.7285 7.14453 cv 27.7285 7.14453 21.9478 0.712891 20.9512 0.671387 cv 19.9541 0.630371 19.7617 4.17676 20.1074 4.82568 cv cp @ 58.8945 19.626 mo 58.8945 19.626 59.7578 16.0024 59.0605 14.9668 cv 58.3633 13.9316 56.438 14.0552 55.5107 14.3677 cv 54.0498 14.8604 53.1641 15.1973 53.1641 15.1973 cv 53.1641 15.1973 51.8555 15.5781 50.6616 15.3877 cv 49.6948 15.2334 49.7598 13.811 49.9067 13.3423 cv 50.0557 12.8682 52.4707 10.9414 54.125 10.5 cv 57.2769 9.65869 59.2891 9.89893 61.0518 10.5894 cv 62.8145 11.2798 63.8218 12.2896 64.5146 14.3677 cv 65.208 16.4458 64.9385 25.3555 64.2788 27.0728 cv 63.73 28.5034 61.4751 30.8989 57.8066 30.8989 cv 55.0049 30.8989 52.1284 29.7036 50.3921 28.1274 cv 48.8809 26.7549 47.0156 24.6528 46.7056 22.752 cv 46.4629 21.2612 47.1992 19.9507 48.314 19.4873 cv 50.0845 18.7505 54.2207 18.7109 56.2979 19.123 cv 58.8945 19.626 li cp ef 58.8945 19.626 mo 58.8945 19.626 59.7578 16.0024 59.0605 14.9668 cv 58.3633 13.9316 56.438 14.0552 55.5107 14.3677 cv 54.0498 14.8604 53.1641 15.1973 53.1641 15.1973 cv 53.1641 15.1973 51.8555 15.5781 50.6616 15.3877 cv 49.6948 15.2334 49.7598 13.811 49.9067 13.3423 cv 50.0557 12.8682 52.4707 10.9414 54.125 10.5 cv 57.2769 9.65869 59.2891 9.89893 61.0518 10.5894 cv 62.8145 11.2798 63.8218 12.2896 64.5146 14.3677 cv 65.208 16.4458 64.9385 25.3555 64.2788 27.0728 cv 63.73 28.5034 61.4751 30.8989 57.8066 30.8989 cv 55.0049 30.8989 52.1284 29.7036 50.3921 28.1274 cv 48.8809 26.7549 47.0156 24.6528 46.7056 22.752 cv 46.4629 21.2612 47.1992 19.9507 48.314 19.4873 cv 50.0845 18.7505 54.2207 18.7109 56.2979 19.123 cv 58.8945 19.626 li cp @ 58.1675 23.1968 mo 58.1675 24.5225 56.7754 26.0493 54.876 26.0493 cv 52.9756 26.0493 51.0454 24.2803 51.0454 22.9546 cv 51.0454 21.6289 52.585 20.5537 54.4854 20.5537 cv 56.3848 20.5537 58.1675 21.8711 58.1675 23.1968 cv cp 0 0 0 0 cmyk ef 78.0986 21.1992 mo 79.4956 21.1992 82.4839 11.9927 83.1226 11.7246 cv 83.8154 11.4346 84.9946 11.1543 85.7188 11.5015 cv 86.707 11.9751 89.6377 20.856 90.3521 21.1738 cv 91.1172 21.5137 93.043 16.5435 94.0317 15.3516 cv 94.9287 14.2695 100.158 9.42334 100.559 9.42334 cv 100.958 9.42334 100.894 9.78711 100.894 10.4829 cv 100.894 11.1782 100.265 19.1211 98.8799 21.5464 cv 97.4946 23.9712 94.0806 27.8457 91.439 28.1274 cv 90.1279 28.2666 86.4116 22.5854 85.958 21.1992 cv 85.6694 20.3164 84.3345 20.5088 83.855 21.1992 cv 83.5454 21.646 79.4253 30.7979 78.0986 31.2925 cv 76.874 31.749 75.2905 31.8267 74.9351 31.1963 cv 74.5796 30.5659 68.2305 17.5669 67.7085 15.6592 cv 67.3428 14.3228 67.3613 11.1563 67.7085 10.8091 cv 68.0552 10.4624 68.3989 9.42822 69.4395 9.77344 cv 71.5767 10.4829 77.5449 21.1992 78.0986 21.1992 cv cp 0.831372 0.658823 0.576471 0.698039 cmyk ef 78.0986 21.1992 mo 79.4956 21.1992 82.4839 11.9927 83.1226 11.7246 cv 83.8154 11.4346 84.9946 11.1543 85.7188 11.5015 cv 86.707 11.9751 89.6377 20.856 90.3521 21.1738 cv 91.1172 21.5137 93.043 16.5435 94.0317 15.3516 cv 94.9287 14.2695 100.158 9.42334 100.559 9.42334 cv 100.958 9.42334 100.894 9.78711 100.894 10.4829 cv 100.894 11.1782 100.265 19.1211 98.8799 21.5464 cv 97.4946 23.9712 94.0806 27.8457 91.439 28.1274 cv 90.1279 28.2666 86.4116 22.5854 85.958 21.1992 cv 85.6694 20.3164 84.3345 20.5088 83.855 21.1992 cv 83.5454 21.646 79.4253 30.7979 78.0986 31.2925 cv 76.874 31.749 75.2905 31.8267 74.9351 31.1963 cv 74.5796 30.5659 68.2305 17.5669 67.7085 15.6592 cv 67.3428 14.3228 67.3613 11.1563 67.7085 10.8091 cv 68.0552 10.4624 68.3989 9.42822 69.4395 9.77344 cv 71.5767 10.4829 77.5449 21.1992 78.0986 21.1992 cv cp @ 102.028 28.7593 mo 102.028 28.7593 107.744 29.7178 109.822 29.0254 cv 111.9 28.3335 115.95 26.0493 116.127 23.5435 cv 116.243 21.9033 115.505 20.7734 114.119 19.8169 cv 112.844 18.936 109.721 17.2871 109.721 15.5698 cv 109.721 14.3452 111.57 13.4556 112.607 13.4556 cv 113.643 13.4556 114.81 14.1133 116.889 12.4614 cv 118.968 10.8091 118.584 10.0757 118.584 9.74951 cv 118.584 9.42334 118.275 8.73291 117.582 8.73291 cv 116.889 8.73291 112.042 8.73291 109.612 9.42334 cv 107.074 10.1445 103.743 11.2061 103.729 14.2729 cv 103.715 17.3403 109.067 20.085 109.718 21.7661 cv 110.229 23.085 108.214 24.5381 106.499 25.7915 cv 104.997 26.8892 104.076 27.0298 103.036 27.6963 cv 101.996 28.3623 102.028 28.7593 102.028 28.7593 cv cp ef 102.028 28.7593 mo 102.028 28.7593 107.744 29.7178 109.822 29.0254 cv 111.9 28.3335 115.95 26.0493 116.127 23.5435 cv 116.243 21.9033 115.505 20.7734 114.119 19.8169 cv 112.844 18.936 109.721 17.2871 109.721 15.5698 cv 109.721 14.3452 111.57 13.4556 112.607 13.4556 cv 113.643 13.4556 114.81 14.1133 116.889 12.4614 cv 118.968 10.8091 118.584 10.0757 118.584 9.74951 cv 118.584 9.42334 118.275 8.73291 117.582 8.73291 cv 116.889 8.73291 112.042 8.73291 109.612 9.42334 cv 107.074 10.1445 103.743 11.2061 103.729 14.2729 cv 103.715 17.3403 109.067 20.085 109.718 21.7661 cv 110.229 23.085 108.214 24.5381 106.499 25.7915 cv 104.997 26.8892 104.076 27.0298 103.036 27.6963 cv 101.996 28.3623 102.028 28.7593 102.028 28.7593 cv cp @ 51.2104 22.2256 mo 58.1494 22.9932 li 58.1494 22.9932 57.8701 20.8027 54.9448 20.5801 cv 52.0967 20.3638 51.2104 22.2256 51.2104 22.2256 cv cp 0.00392157 0.909804 0.776471 0 cmyk f 51.1587 22.3525 mo 51.9009 22.4307 li 51.9009 22.4297 52.6211 21.2217 54.5454 21.2285 cv 57.8428 21.2407 58.1494 22.9941 58.1494 22.9932 cv 58.1494 22.9932 57.8711 20.7905 54.9448 20.5801 cv 51.9351 20.3638 51.1587 22.3525 51.1587 22.3525 cv cp 0 0 0 0 cmyk f %ADOBeginClientInjection: EndPageContent "AI11EPS" userdict /annotatepage 2 copy known {get exec}{pop pop} ifelse %ADOEndClientInjection: EndPageContent "AI11EPS" grestore grestore pgrs %%PageTrailer %ADOBeginClientInjection: PageTrailer Start "AI11EPS" [/EMC AI11_PDFMark5 [/NamespacePop AI11_PDFMark5 %ADOEndClientInjection: PageTrailer Start "AI11EPS" [ [/CSA [/0 ]] ] del_res /UGSOPT+SandRegular*1 uf /UGSOPT+SandRegular uf /SandRegular uf Adobe_AGM_Image/pt gx Adobe_CoolType_Core/pt get exec Adobe_AGM_Core/pt gx currentdict Adobe_AGM_Utils eq {end} if %%Trailer Adobe_AGM_Image/dt get exec Adobe_CoolType_Core/dt get exec Adobe_AGM_Core/dt get exec %%EOF %AI9_PrintingDataEnd userdict /AI9_read_buffer 256 string put userdict begin /ai9_skip_data { mark { currentfile AI9_read_buffer { readline } stopped { } { not { exit } if (%AI9_PrivateDataEnd) eq { exit } if } ifelse } loop cleartomark } def end userdict /ai9_skip_data get exec %AI9_PrivateDataBegin %!PS-Adobe-3.0 EPSF-3.0 %%Creator: Adobe Illustrator(R) 13.0 %%AI8_CreatorVersion: 13.0.1 %%For: (Tomas Selander) () %%Title: (yaws.eps) %%CreationDate: 12/29/11 2:33 PM %AI9_DataStream %Gb"-6H]fYrEMn)6\3p5t&O9l(l/lm_l\H"9@qY:$=e058cA'c3W,@(=lQ$J%0 %7(AY7Y,ZAHplBlGnauAAec"OoMl2(#ltdU6ZSHH3gFRjCqr(%0qL@s`H2%=12)!*7:\qpEl`q4Mp%Dj$VbpLJ?7buPlWlZer:oFB %n\[$:4h\LTs8MTRiT]1qcd".mGPcXYo@qmfbjF*@h*!k_rU\^]_sPY)VH%N**^@_=^V"uBouju!+!5CXV'j%Uq"F*mrS=MM^$,7e %r:S>5_qiSd]/R2@cLr',/h>u6(E`)f?N&-h2nunMpXr[iD=R8+IAUAbQOb=59E4C;5C\(VnF>&b0B?'f^&%Yd4T/TY=MM:oIsLeI %KBrnilQVtdo&kMsZht7s3u_MmFWU6NriqI34RW',1,%CVs4Fehgf&>q>[eYF> %/%jN_s*+J"5HB2!%j13\n_%IV?N.TSB,FtQr(D=ilc3(n:N*U)A:XXB6AEFRN2;<-fD]%QgRaPX5JB;YqCq="s7l-K_qf[mf#-=s %^7;reGPb0[B4]lDO0A!?hT7SBc]:,kc7``/h`j6YSmUBhr:o7=r,4d?@;pGi"^cF4s&H.?lS#fVXe!Y>GUGl?RtnV*3PTF7nb$g; %j"It54'V;qIcmcgV,ctneU-3O]t`\n^#hLbo4XUXS3QgbTDZ)ml*X=Wg*cnK+8r#XrM:Uj9+U2-j0c(.?ba=%GQ(2ui8*5b9A/4c %mm#U@HdH^$rpHTm]^t$.I!E0uE;oS)SaM'o^OLJ%GlHjcl/KUefCA=-GH\`kP>0jthW_f4gqJ:6nNe+A_6#9/]Dpp3]D).J?TnAZj8%NG %]R75;A,he@FoV%+5urfL^6)q#rpfg)GV&oD\9mi>iSj3o&$=r?67@<_&b$X\>]U<.&;m3R+hS6fi:MY;I]X`Id:<0u:!UOC,0C=;Z %6e[Ub_tgb`+(*p>qtT=4p>ZB<%\Fg2IXD(bB4l]=:\r2P0Qm?hnjt'[cd'7"VrmD(rTj(Qe9QM2T-h;K %0>9_\+?+NRl3GFsQ'McYq^`$NG]RZ#Af,G7P>AN2:"!b(99DmN,`mSW.d=(I,tPrqagq %^%oq%_q4)NGPB?phj%QlY5O(HMk2d9J+H^5ftRI)_af";YMMEjI/Ea"2c#2N+(%20k"^)\T#b92IIWeV&>9!_m)M?&IJBp5(\urT %JVT#q+3XHUoo%T%[m0\@S,DiRT#0?T?+g(0rnFc_St7!6;g@T0S/38iK5r_qJ#?)40)Eb0rti-d^6R&CM"Q0-:)84FaQ,s8=p:O*Y]l9g72gqUq&`GgpVs;r$\gQgZ5OiU;8g %I[dfZs2!Pd6GI`M2sj2iMDa-JPFu8Qg4Kmsmr44&*:D_!Bno/]'*%sk)nNWX7WP6sWGLhr1Vr/:EVB$&p6'mr %a+*kOgX^d&^jRM!nWt?d5MWYBq;M&;rU$XAI8a;Dc=[rSl05r\fZQkWZa1bRp&3o8r9Ji^GP86?6i-AkPP4!=q8qUi//P%AB,@`sCB&bnKDm=;1t5qT,c_jWiF9;: %Y(l9$V@8X!N+FKFSD7.*2=9L-0$7b9.bE]'hdd_m3027mNr+&@0?23*l7cP*2q'IGBq2&7SsF)][V;@oe&?Dh>trpnW25MsWjU-@ %-.T[MlUALg=7p/Hjt`"h1tR#EQW^Wmq088[k0*R8^0-2e/E8KWZ6s@a,d.#b>V;>cja+I?LUF5D>1\%*eofg"I6F_LlfEH#?EZJEa8KJ^PfM='^#/08a5L-\nm.=*;*O\n4tanKE0MpppZ(dg %+cjh,Pru412]&bE0?V7Y+lE3l?Ha5V@5$2im6\600>+g)PfM=nou51pc/inI/nP&fek>hELWedW55V1(3-f;mU:aD(>[:[Zj6#pp %C:KEj\/OH`?.HiBCAg+q:MO5hkY:lkdA+6JVc#b0YN;Y:B\sl,F/98>K-cXsSLbWEK#"Uc,(r7V_a(c,,.R$sV\EJIj+i?T%fYGn.1YV>dAFSgP %OTBR>(t):RWGtlkNbfCM\**^WHVsYo+.'MS[3+(ga661^bl\I*Z0TRbqXW)3161&N]m8%mLH'[p2c'=Wn'0X[m*SJuk`,?#5rt6c %[J/n9p#r7FkdC/#o^%C*jWWOXp3>f4QQ9mJ]\.Mpa)#-@06fAqN_$JKcnU(3*^NkG8O3o"I:h@Y6 %e5;Xu+sZ\u!gqkt(Q:j)NT>sQ77X#34rnu*mLD/='Ha*0[+31KV2_Z&,Kijp7i>%Q7Y]%1$bHh9.iB[sKZVSCF[4#M\<`1;*i,i< %l,O1r[2\A28Ij0CNm(-V*fD"pZb1GtKF>Kth4sZ'c-=N+c':!WioVZ0m3[I"Ob$_T-95\\c#A)PI=6Mi>e[^3?LKW^hrXj?X6rC?6b3WZ34X*&<-d5hC$)?-5HU %PTt".S[unFXg3RLg!,-hQ$ROYb)S^/mbafR(?p]+*AU6r$jSf@YN:STP[j_A%+p4;MtC>@4rgCHLO(1nH6k_$+oT$r@CZ_DAg>MJ %Zl,_[6-kgTL'rR[5&CNB+,dA"b%MZH>(c>1>"6l8N235-VbP1],-7h#b!nCVrQpTio],E+ab(`6HgSqm`IOQXT))@2521;FbO=5U %#Ofr&[l7N@*n[1DXZrX(le.?5^3D"3aPbZTG@H]<\c94QPu)VrBFHBS3+4b6XeE/SkZC`VPsUP7n-\4D[]Gha:7;t6di %O3n$C#smHZ5p%2,4]X['$O$F5=[73oe0?$$cQ:^*@0a9D^L_TNhcmDH(,,W@XVXt;-:`8cZoL+L7CZXQc-U\uXoCP)d3KC)Qd %>Zk0VBtO7U@5>H'4]pV*A%#KCs#XAe9bPtjO0mTPd_?iVlU0\SIiRLRQ1[s)9+MrkBr/?R=EVF$7h.hh.ar,i>%o&m@F^?s %,GiooL>QIQRVguA`iJEX%<=Z63O'>=*n?!u%0g=n-)brpeC+@Mf%\p1U\2c;WUf^JrjoCFqe6#]:>O9d$]Z=n8_MpPm-nd`A?KQ- %g?>0ui#"$8BRP;]a)sMI%TiYm1*.8%36#IK@uJAGO!PjR4q@9fNCP52Ql[Op"!:^3LrXX#Xq'io?04?fl#BCX]mFSO6VAWh_>gf^ %o''Y%%j0^.LMt+:F,e5"5Butmpq4Q(:T?6V*Fenna#+q9OSn>0/+NSm+7>6V6gUc(H*L#s:2W/-F[tbl3?HV,#B]*s*j+2koJi_g %7=(d/dZMK\VLPaE*]NIp]0"IL.ke?(A2bOpU"*>XEa<%RlUu@jPj3YKGbNCf8+f4) %@\)snhTBpkd\0'ArT#!Z*T=WdGI$U/435T2Nqh!mTN"`W-nhrbTga^l*qF;T"=<6T9DS"V@;`lkE#5D9WD66((WNU-B9=,pp[!X2 %EO_,C^CQ7S.V:\$*9H2rMd]Y3R9"Qji(h1OUO@tb2X$"n"j4?=(N=4)&SruJ4O!LAqe3M0fQrYJX,";.b-ORdEqiq^hVE`Qlp9BU %;<"+MmoJea$gb2=gLn74FBA9>E@)i\B+3*7IK^rYP%Q>lBO9\DgI*PlZZOmN/O*7s8i=fI2-T5"rJt$AX?pL+_$)^5C=PY3QmOna %lGH7dK:Q*:iC,(R^L!W-FL3;h+0AN(jf@([]6_9V@H6H%4btWhcr(]Q@X<]5*fOA@3&)NB!*jA&H8s39:/j;L:Pa?S=L%FXQJt`, %]>COO%dns\)b6s,fg3=8+0Y%qq099r6Q\W"/HDNPX8KQ5a3dZN]:Ie)+ZWY"1*_1QF1p]_qQMd=Q(@M"XlJbIl_dtuS>Pp,.%)9L %nj#hHmJeaVbj2S0n'uB*Li`$E`EHSt]s8RC"X5Rj4H?@nq1&,E_N'p8Cn;0_[f>X^Ab3cqd? %>cFbOXm)%q9mD]AB15+$g,mn#2koE`\;D9Io:FL#/6%SB!Pe:J[9>VfI<4i %d&NY*rT(&lIC2]FNpCE"'^N.TO7=57]*#o2&*OkPXm'Si7;g>0p9aMlEVekhjDf>5OO%s'^bZ.d-R%\f.,"p%-\:O@1d6mPPokF1 %]QT?"^>9B+n9sXErV,XXF?sDor[kk/M*[&;],9-EL]Q2R'bZoZOqq*]EddA_6?cV.P;E*p=de\\an7aGl(V("pk,ES<-\AEFk6`E %h`kFnrGK$S_fmWEG4i<\dkG^pGW*2Ob.\9FB6]MOdUs2rlSqt8.IN+#lt$nsT8fa+]0C3a([pI,%%NSHlMU9GfCRO7"l62]\QYRW %s-W(8N3\-u]bmX6Cb;r'S(d'$?FFIES#;#],FPs6c\)LkP+2"oVMdEZaDSa3Y5h#?%]nR==Tpd)pH`uD-i6olMX+X&9=oZ2_S%)ehGQ?9Fif!!k>pD$.3ChKj'QYVX1fNoCHQp"c$Z1d+` %=qk^%9!pHI[B3,L6qV`5<4XnMh'f86.VI;CVUmPJD07YM*=[.X.&KY+W=[!*eg[bT[qi(c\=@ti5_33R;iFafY:-a;qWe(edI;AW %;tAtAF,B`^-SM^1fkT]R`QhnuS]@b$b9fu0:3mi$n.f-'GL?)+Vg\R>C5cJ,d7Cn9ApsYkp8p(%]UXaB#]:cK]L[XaGCK %/8OW+"+5Tfr)7(&?TgU0^:AT5p)8k7[RDC<:G(tnVG#.)4T4`&?-g9AlhHE&2I*iN,F2O"EkOq<@lWT&?ti]OB++'VY&) %4[b%O!8rVrZ\&k#Sfd&V^AZ-m0eEX;*mApImftq7IJ2i71T@N3m??!^B?i6:F5Re1KP[%%iU\@7R[\<"W!Gfrg!U=)BUlna`49Zi %1WNt0:%`Rm`]SF1ZDj*1%NVYQ^SP(.MhOsWMY3a8=)^mec7RXKd_EXZk/&`a95Jd-X/)d"DR5%:'d;Cddne?n_]qAb""fGDZj?2X %BMlA@J,jVr@+)s8`Bqce'8n4G5hi*u2LS^`B91785_/E^nE#-m)"m?FK=9[c7JqP\5$t,3fAuO.dlb[XRp2=oPid7eH1#@;/:)q_ %HN*Cnc=8mqp(!JP=CX\i'%7k&KSO9iUHCM__EYcL#QI?MH+:TY+B0_.iSafP-k1FFGV&BhWH#B(^>jms5B6qRE],Gg+$M\jp%`.K %I-kft2H)J=Z9*.AfOV=jL)js7?+QHuI3N[\W3%e>XBGI7<\V=JfgVHpdT(N8$hRqbmuGR;Esluj90 %9'>Ks=CHVK#"f?fAAn_Ch:*'DUpF=]ZLPaX$M*bJk2l3NY4;!2:V1Z1;p'@XNn<`="YX0PiC+hpp:30@b)]p,\`p9\N>D$[[3*/h %a"'E(%EP^Sol8sb&j1U2d28Xts7LWC%h\iSmJNZfn5&j3NV:gtpjj<>,Cf7UnCu\Vs8"tHa(-HIm+Z15M_`Rjji(grICL&.Xu\4G %RH:Jt[*mn&XjmCZIQ?Y2IqR%+/H>VQ=np(pp3V#7jjSSZJqqOnrtum',BEC3b_e_"PuREVMjfm9!qrkc.Z`7]^>/3>DOpWU$AAq,^%r021dZ%90_-s %S',2X,NkRKG/,4*oWlZsT,-2fJg36\DHne3WFgc,WNTWabo/s/+/h:"+-[Wh@cME-@d_BuDI_%`j %q*<,Wq<unmCQBOhqHrM`ATG(,C6]1d!WpKn"_&!^6#\DBWkQ] %5ZA.#H+lrcf9,`Cd3cJ0R_hs$FI%>A%8Z %*M&jFQF7t"+DVH(G3`,fP=^jFa.jn^rgIT*O[RIOArpr)a(Q?"SS]51#`sN0O&l0DX"oLtl\oni6ZX,S%nq,3mDrD/qEE>unpRks %B:iIb`%'q_D-L@Ud*1f`YGoK1NMLd1D.;!IP.q5^i2!IZ?5o?&]o@F08RGD^h:bnnD9pDf5a0TrleKS]k:-_Pgk/@gNDkp6Rq6E3PP-+jG"4T! %2Ynf0!BnWBYcNh+g+INiUm"7%;B+l-?04U;D,54K\lfQe,tOpe):ptG,UU9dk]Eg0V5$,@+R\3IQ)-a+0\fI@q0m[]%]+S@4=XarmVL_;?@XVn(BmQ[kU?`hPV*S2OH0#_R-nc.6S> %`nB4K>;/h+9.=)c3;rOC_3Z&"UqOs..Mu7[BU#3](ak6=?/ml!S2;#eX"dA@7M[p)gS@8+VB$0?n$'Ts]d[k*4[#B%Z %Su/ojS1YaDDD]M4D(+MQ\R=?XEq\(U9,Qct]fJiHEk]iQ;9kJQk[B^^\+,*p.&VE&02"eqh31:I""C-2Wk3kIP9-q,F?iSkd^2c& %>ZJ5t:'BWoi+^i2+D6>5XoUPpmk@J=L%]=u,.I<_a]gS@-BMOONpeSEq@W %D9iks?.KWiHUUP3[=+LR:0X@#C-*fGdQUB1F\tn=V;3H#qYY'e3c/0^WiP4!eMbf&Y-o`)Y1h0XX0k_9='_+*=)I-=SjGT-^YG-mc%El4V]04AT3n=dQWj]1ZD*I@@[sTheqZcmPuB.ui#r[?a!rQ$/M(f((qCQ";sqQ"Ecr %[<\4NlEZqiC-*`E[6.5iAQbA0C-*fGg-/59F]hIEdl*/+ja#ih9:r`JCJs/,m?>K=QDMOMhBjPO]$8^BdZY7ii3+A1i_&c %PS2S^mh8bCG,L1t%F(-IC-*fG3h/tZf4jOa=$$O_ibIkE`7:0M`)YPPEOBt^\5$8#\6:s?Y1ikSi]<@fM5r7%M5rOUi[X>.M5r8P %Mc$7&Y1*"oEKrsui[X=JERj5J'3A>f-*G\a&m&d393c%2:0a^N-*Gra9jDgD:0aol'%a*H:L&$F %:0aXO-*Grc9jDh3S@GG5.-e0bR^c,#:L*9E.<2ch8`FL.;W=_DS@Ik94&&t&8*7b?qD0G#3^QRTf;WkKlW!`!e]-E:ii6KE-a$D4 %'3Am493cUukJYp'OqLi3T-USJ/1%HBgn_m==O\_$b*nj1>!"%5gAY(23_n!6='_%(=)I-=Y'M5r2MM5rISi[W2cM5r2n %'%_-k'3Am493c%2Qai&sT=@Mj=lLpS]#7V&?/dmtcP+oMknDZgkn7'35"f.'=\`50SJ0UpH(MP2ZCJEs]1ZD:I@@\2ZCJG%D(+MQ %H()7s>GoD>gGs9HFo'&,QDMOMhBjPO\joL/=5B'#ERc,TM6$:DC#Z-;.4)-,m1WP?GUJ?K%F13JC-*fG3hT7^f5^'h=$$[cibIkE %`7:0M`76Tk&m)tIT=>f@;W;HYPdkK*;i,:XT-peQX]$C8`)YO;'%aG]M6""q`3h/B&m&5#&m&diM/-7d-a'bV93e=L-*GZ[9jD7,QafZ" %93e=l/9*7GT=@M*93e=l/9-qd3H:SjB][a8u %Ug#Eh/X^^l;'cZC[jneJa=?G]NFO>,\(\!SJol=3O+'>3kuQ&5SV0;?eah9?8@MaYg.8\UhE#hUdi/8KZ&t/de%Bg*K63UEX^+aN %G`kA(&9YT2XsHoBV>B#Q(9#tFESZpGh/8)8ge]plb?W6;B<3\A-#:.I\-p,m9L %1`e5qONu#1q\5j\CsC[r:=!dPLMTGkc-k/t8@L`X>BLO!:'I102:L2%]$7P30nXAMXL1K=Rq8^#J8V]p[6=\`FS97On1s54b?Ja4 %dL@*"Xm6n,)`2UV[Q^i51j.VXm]&MOjgtc))`2aZ*37#K_IFUQ`k0(8aZ<<`)1jOE& %69ItSVoHEtP1eQp=\WMog1Ra\bW6\+S$cO$=uNG'm!Ou@C,28f]M[#L9?Uop94gh(ZEn'W6(XB&AK5,3=j9^*=[,KcR[kb2V:Foh %R@WMAZd[]C>5F\Y-DE\q]On(`XOGX6G+-X$]@H7!R@RO+cLR#NC3Goef"Paoam;'tRN:A'R[kb2;dZlsPM+&ufp9iWcZ@d];VB&Q %-.=uZ/]NtpJmb\!G[2r&YT9Su\>R6iIdJ_N:BtM9*=[FL-*uVEll.LFof?Kr:CfAj7;C1F%u!o:-1GOToQ6E#W!cUm#QeT<)$1&d %Bg![d!s_J64[Lq1%[PXk\7H?o/?Nb'HjL.O+5_LV]!iV5hnK!Dfk7VSa$9ICg%gsVoKKWp5Q:6.gUDBMF&ou0Uu'bu-YNIG^?G?= %?hF./?=I<(Z'\jCEH-C%o&H3H5(0XSq"bBuDu%0GmoKb>'/+3o\GS]AL+d1(rlNjNrr33uN;hi+aa)8]e'.J54fM-?U0O+n"*mK0 %V"a&;8YsijUj:C7$#<*'V"`?\Uu>cWe"l`P19'Zib+p,&4('j_Bnl9ZX>4LJ;J":DPq&!;\RiPt>ha<[RL/jiXCd %X]1]FKUl'hosM=c.=ZQ,8`e>kA^YPI.[0]l'?bMWS5ptZ:Z]`pOsF*UXY3F!PM4!d121$a.[,$1<22Wd*p_;uk=_6#hPq&!K:6eCfkK;kX %:%4(U&Ac+3]liV]CdXp)ct@p\h>f_n&S^dG$t8&d.6b4;@*AZJ][T!?!*t=SnI&q\5Tf0gQ?IgN(?f]#CahW9k\ot6hCV!ZkH"n5 %:*2>nX=6mdOg=%-I2l9pLLL%bj,do@^i5*4Z7:T$6m/qDNRm'`klK$`HKrJ?I>`IM/=>:b!nZQb_8Z)Zk+aBA6/_oQ_GT %^dEc==+i_mck5pE+hEZ2(8?kde1$1:lW!.`Lb<1H8MU(MTTX)%=;c8Dd.JQnVr''mhoFErRu#GQPbeP`5!mj8d36^>>mBlTXuY_J %B'h$6T2T\Mn3LkC1g$*)lT/TL50]C'o5,GU7Wro8G=E_T:=9%Qs$oV^k1EMALfstgET=$9de:,XJ6JF'Cg'*kN`n_.D,T-RZ)%p\ %$oWtZdCW@5Lr"r7GHe@@gfqj.#[d5'>C-\o`)o,L7XXP7Fn*=#6Y\d_TjkAoX;ofIVECYTBFeS\WJb[E6>AZe %p&VQnTmLJS2/<;n?`_)jgf*pnBil]lgh#De;HcC/NVI==uuiXCFl42p+k6UW3u*$f%D6^ %fC:=7BT8smcS6/*,AK"oCTM"X[4\da3k$8BD6>Id??@*AKI\XM[Nf=Qn6%TDf&9hC*S1GWXc'.N#aiHhn7tlZH.Y6kaTH$i_VVjj1/^6?Q_.F:e\YMkdi>,;VZ>&4o-l@.%:F!`bG,^H%hI3GT %X]%X;g>5!K["qm?Zqc$?XiiO8A4UR@nI3Z/C2M/H@qGGm&A+TLLrKarHI0l__l-?#SX7-jc:&diO&>SZI@U'E[FClQ7Q!A9CX5j@ %:tO,TWi,9%C)kdGB\mVHe\cj>%Ap.Dmu=0tF<@oq<0n&0A#U*[_<("/E;bmn7->(+j$(eD=eD"/D`sQ]@fO)s:+NU9G/a+`P<85,iLSt]lWFmW.C*FLpD?&8jB5#,*lksQ4V!h_)DT;$L'$f:SGp_LoP8pK\E4X8rDB%P6@ZE->)riu&HrKXi %om4NFq:8aV]U9W(mD,2@gT-s=%<&+dDiJ\dSiXO;U1"A@dD%$bZu+E='&LjmhPS)XDI]'S^mhe2a!61Rq??&]"Pmm\m;,2#6+;,rF-=pF %NG\Qp"Q3#.3a!iZ9btibB+;GOT<),'Lc:%S_.:9J`U041a)PntI&"NK %q.B*_M3[Hke#toM1;K8ZYh`^Zg^0,A8RuD8H6M>!WpnkoOnXnpI@t1XFd`FEeH$/EIAqSPg7iO;U %=.,BTS-n$"]Q\nT+g/T"6c)^/-K2&nBF_o41B1Vm,Fl0.!1YcWgcE=J%nKA[\G0nD&C)87&24^AXN5P0K[W@**eSFc?9FQS_O2ZP %QB#paBE%k'>+2C %1s24X?K[uORH>R?"m5ISJ=_KUgLjIFS4]rJ#D<+='k-dIO`W)!>0RVS1Y:3Aa<7$&\P%HJ[;A1Q5c7d01=3#^CZc%T %:;-%?8t8goH`_(&:8R>pR"KJ1-J"EAF"2%YGmVcqZooUL;pM@W>Wi)nd&FC3i71)jMXn37!P6Fd-BYI*E!+HeVFCQV=jWc;#3]%% %*el[?VsSUF"*>l0O(/DU>unX#% %\KdZ*UtN"`UoS#Y87s/c>!(0ckaY,*:7Jst".bJ8Fe1Y@WO0@j0gKAbg#i@+*>>$!#O#ulkK!igC\r:7FN1%plptdD/SgHng;=i) %UE"_L3YSmPRRoI&*8K8ReHthl5roZ24\-"0l*@U3+IsFpW6$LQ9P@c/Cj"`5+FnR2BWj!leb6NHfr?OVo@C3IPG^S)1X]EQm*eth %Y%K^`]#j*GX[,!b0:o?MktKN3>Is+ZG7DugDXR%#ONoEMZ)+K7juS]JC:(-2T<=UhlcY6/Ck281:D#, %l;TA`@3aS>!LT'G008J0F?3FN@t,Q^n4nUX6R/n!:7g?<5c6CokE`9NZb>ic$9EI=D=-ppFgecUjf@MlHPO=^=&?r]TX3?E93A;Z %[Y30nBKqV:d`JdU["PjPB:;F;ST`+WHIAc]3jt81[R&=VSQFRDXS1MB!]fN;24i\bkt9-$831$5\!5G"VRD`>,k[aMZ6RtpAZXGN %>T''\!Ob?62dp!9;;AR75Jcrk]:"*B9lSo_?n %dW/B(%kVEOcau<_=XT]#]69\pQmY/E(!kASmg`X'=FuR*u/cc_?H1_+fm( %S@6Vh@nsN!=">83C2fM/3M#?A/3W)!<1c]A4j(G:jXJLVD5q@URWgJG-V,1<8!kUEl*$g?J)Ya@W!r6F:HGgk`a6$aY"!?_)W6g#6]"g3GI6LhorW&LY"9bk>Y9diYjd8 %0a1.=Roj)"k9d&\i1.@.hSI#g?"VP_^c?PEkHS%LZp!@t(cgbcpDTQ[D1H]]p>HmVZaXh/X1\S$kA%(QB?Jo%PdtOUX!K0,6Mb"M %cKU?/4A%BS=a.;EoK]Bc %J50BSS[X\PVb6C+jW"An>2(=.*^"1S,7Y10WO9FhQFX$'?.UMjVlhbX %:CqWC%_+7/-ikTUCEJN7ROWp\cpL$f@0>r$[9Y,5@U<.$r+RpHm>`i8RB %eoh?dgZ.($WbB#irCds6[=+g)3"s$>k\#^Xp<_,dZ-E.,"Cmr>hL=/!(hYn=+#C_m?+)A&[Yg"'HSA4LZNk]j3;nS>V_P@4f0%/7 %F]l2UT<;(n\@;b'e=3"-cDm?#^@p#U<6%uDQAeaPg\GE:.p@)3okG[GQ8/"e`_"oscB3*]A!^(,j4),XOr"t5rq<_,kplNlQkt]3 %.\sJB+lD.nj?d3)uP?cVFX`Am]In[S"s&W[n02D&6HS,33k!0XTL_Ymirn %gNDanX4VdN0d(,4_,[i\lZBI5CsgaEX-c"5[Fm&+p!aGrOAfY9gY-HYld'PZaQX8hrVAfFY37Nbei$g1OLLmQ%DB$=Y+igTo9h?l %Cp]]r29\X=R&5>DMN78\0-V7q$nQ1`Y$u6DQ322OUj+5%S9*,[_)Wafcqd`Jm0mjCMRIL*gGij5iRr;fqsDM5$g4Us3S!&Xrno1+ %7HL%CPl'%pXm0l#A@JRO#pIVdVhK(pSdNtEi$Ra=hOa[tXJ&C=*Cpm]s.*lC83agX9GJ[Gp3$nlGWjb,NY0dj&mUD?]=g)O61U\Rg//" %_D,`gW7)XI-!uI)++##4hQ":JR;Af@0W?FpcIK8@3h;eTb`-a4]20*@)t7nhA=_Lh),bM62ImN]MS[$g2ns/oS-d;p/B>*M6Nl>4C!G*U32K,?r>q[6)F&e`ZSF&>uo`SW"iL %pV9%lHsKC7:ne&qCjk0?ea_Yl3#shZ9F"?&F>BFhbaJjbD0dYV=#&&N=k9udE8B;/mQbF"AR*pm=$t6f5c6"KOBE3>S]@+;d&B. %9P(2UjAZmU#W#WK+=u2C#K\8Rl6%Y2fjWDd=o'7HaUUL*PjFL`Y[RhZUoW.]E2>cKFq@!7@L"'PX4T]DM2E=__297lOKN,l7S&F- %BS8du%Rs!lfg,n#RN7'CW7aHBl"YAQ66_\K&/%h]KTIh/K+JYm*fQ2:nmI,]psB?Jr'CZ4rB^e3p^86ur%fL,BQ^rV5r&EFn$OkU %81B2p$n3GH0WYgP0WYg`0W^?L%/q1ag],hK[a+JB%4H!:3]Cm:Y@]A0-]W2"]qq(RFKX9/`k6<_7WaC<]I[KOBRBJ\DU8E_:$hq^ %@d;#c0g's$X875mf%HsS>A[Ok[4NP2qcud.Qm4Ku%Yfb-,LW1+>2pX10WS.8(9#hg'[_(QH^H%arm]d;T?>@iSQn%_d\4"3CkeNc %b[umZeYd%h'f/@%imbF)@?0QiWHAPfKK$HW.R##XLA,0;cu)d7ho&B3A@CB^KY._57$d'tOlD2B?S)1d+*PJ#g[c--J=W-F*i*Qn %-B;co1^]$`2Wo)EeIc)q\Q`jU)0E#]V&/HE`1hU[A*SkE'e:T[&UfZ;dM:7DI=>9ccS0L[p,cf&#r3F^Gf9<;Wg593DjUJbqJ(B)T"dIu"Q%PpUerLL_Y`"=#mH`Z3c>u=:8'cm'm,FuE$ %3MOP/m;t3Uo[q[Z(g+i&&Xu$GL,bok(cN7kC;Khc.=P0(,0QTWpG4PB+B"qEn>1ub, %QoUnI(+g5U3>/Yc@?0Ro4klQ3b-r!q86k]2a7d0u$"=ROuNtA,qjH5DL"ni4!]"f@18f+s,1.`;7,9Z4PH%[GK+HL&t %/s&SZdY1LF8g07;.!9e\8.'\h8.'^>,H9EB!E.PpBpu`g,99<`NtA+K7foJ=O)u@q4;&Wf4;&Wf4EASAg*<#+e43%il6E)ErK0c6 %qBMf+)^Jr6'p?d#-mV2#'bV^N$;!Q(%2'kF"pl.PK-V\%"pkl3K7o&U6';gMK7o&U5siN++N];35siH)+9CCCOCZ'k+Dl&e^47Rtu\`OpOX4"GEO96H$\_ab6ET6Gh+m+lR*rAAZan+Q7!q %&90Nt1?3&0OE"tR`]+k^R;k&S^c2ZHA/kc9bW$Fb6lZXK,)uk!AfM6m0TH2@)+T6'1QDMC)+T72N2&Y$)+T72OJ>*.aO)-POJ>*. %b0_>',JbiPR;t,T5WK)qKH(/Y9Kmu\R<-kK#Wc]G"S7g"FKUI@N%d3?]:UI@N%V/7(9BTZiXd38VX.$5'aPXmRr %BT\C"Zq*_L=sTMZZq*GD8gL2Q-'Cq`8gL2Q,neXd&kSr@,neW9(("D>M^63#(("D>MhJ=07?V(LMZg8Z6pfU),0@3e6pfU)+sH>% %Odsj[(.kAD2%n>t)@:+JO!N27*XQONPD$<<8s3mYQ%ZN>8j_6/,tYJ=8OD.Y,U)PgP%<:o,U)PgP)siD8M][HP)siD8Otq3,aig4 %8Otq3,bQ/HP"[rp,buGK'#KYQ8VS6S'%2da8^Iqk8Okju,XFL.8HO&H8NPQk,mi97_.BO8X!A_PTTTHETTTHETTXE$K1\J__'B?> %_'J8Q#EpEH#EpEH=/*F_BEnnjBEs_HBEs`sUE*$kTO$<,dgd]r7m!(`U`DjdTO!DeV9oc"8^Iqo8^PaVP)aZ=8]WrK,\.oaP0>tE %,\.oa'!dNA8S/u3'!dNE$"6>f,f>Wh$"6>fKWq4CP$pkE"L+Xl6J+RLafM7.6Io!Z+mUP>4C]C*P)aZ]8V2)=3P2$r/kLgZ\0QVd %fHc#/kTh26TT]NDTT]NDTT`p9_'TK<_'TK<_'\DC#Fcu8k;Gnn%Q6mK\foKb-QR#d+<>9]Nc_KsJon4g8@fEGGB\g"S]2JAK1loV %F.&gK*Ft_2^tk %@7R)GYbP'Y@0`Q\XJ8WZf[2+hYbP&^f[2)jltDVof[2)jltDU`FqdP(lmS)0FqdOS3sm:%FqdP>3sm:0*JKYM3s[-c*JG-CN^?pi-0-&J&o`k/8`h"h&os"1#rtMT,]euD#rr6iKUAN6OtfJ+KUef:6I&FXadf,,6I&FY+m5ehABmIk+m,_g&9H>n1?PO#!->M> %LcJWb)0mEMj;b:b$p#:M"bTVGKgcqu89kU;^,cqu89 %kU;^XFHfBQkpVgYFL4Yr3a*gIFgObs3a*gt*NbK`3a*h;*MjCSN`&G\*MjCSN`$0d8#bR6FgOarl_p)1Fjs%)3dN*?G4\Bt4.7Ik %*S$=34/sUF*Rte^NbV/&*R#/UNb/T;8$aK$Nb/T;8$dlYUKNb"8$dlYUKKq=d4EDLUKKq=d4>=d.$eE!;(NmY.$bEg'MC4L.$bEg %&5.g@MBs-a'MF6DMC!g8La=)0TU#`KL*3h_%VeRj4/aIA4/aIA]:iNC#i7j!+n&g)"Rf`aFM*6/'"ij"'"f_l")Y]''b\03=VAB" %=jlgMAkDKpD8UY^Ak@b>QmK\AM^:[$&nt"6*R'\>*R'\>*R'\,FtcQS4,P>[*Q=184,>29*Q8Z.NabS7*Q8Z.Nb/T+8$aJYNb/T+ %8$dlQUKNag8$`?&UKBk8;(ThnK31Ik;(NmV.$gC/0$KIe]22-k]22.V]5UCun%pY"nA6e$nNnnNa:#\7bR;+;cjRN4;(q8KE\Hbl %JhQJR9Kq/V,[]1M6snRmR=/M1&:S&SOFFQ01B#'B+o]>2!WPJ=aT/,A'(I%(P)/iTQZVa=jH>>n'&>+sK3Zh.I#puFZ$!T&nlj*\ %?!ciC8Yic@9-UKl?IG[XY*VOW$b[fXGgK*p&g$ZXQLJ:K6jXBI8QWc]>nSGG,WVsa_(Ot%GVDLZJd8n5.X80j\dBMFP,R4*orK_iB]*\C3ZsUU4rob,\hS.9=c#_lk62'O@peOK3ZhnH]UlEg4NWCd2qA3$p_r]"CTk.,[f7N)1c4_OFac3aM>#Q %1'GKI!(^$gP=E!(QTq$?dUpR)R8t-_Q=-SU8DAWi*bpP?LFKrlW?njomNW%G`+QE`]DUn5KPB`? %nu)'j9T+X/,4-*pNk$Gs_4\F+"+Fi[Dh^`j`$Pemm4NlgZ^gMQr7;'a]0@"R&m\q6g0O]"G0drCEkj6b$m:ub]$=X9?2jJA]sMD; %^b!kN6+GmMc#D#?\sIT,5Fk(pd!("C@^@PmG*ft$<01^K[T/!bF^UNf:9$sc-+Xcg?6NpHk^M*c_^]8akd#VRGPST@+a^iET6B&/ %SH^U_k*9cM/q;TprC5!^Z)L8uJ!WB*[L`$^D.A8#ZM;5aql@clBVAGHk.%n4r9;S!p3)ce*SU*%HbdiSJK>>tL>rK/rP3<[#@idF!F>B%ThiGV<59.jN>FJ]hmBX.3r97IXV;7?VbS$E&;o^RbF<]7' %e"g+#lpe):*@B[jINf59M70mih;qE],`==t.OU;W=oun\D6IH]bFcUeWdb&UUr+V)&n2Pa8RN6A8V^0!-%SpL-%SpL-(1Ot8qNi- %8qNi-8ihu!/0R^C.g_NY/'0>r"Pq4>"QLD>"JrtBI*[XBI*[XGU4A(iKXO>iKXtOoL]`iWKdI\ZqMRle#&;=*s&;=-4 %5nm?k5SRBn5h*3)bYVCf_,+5[_,+5[V[T+N`uu+6L/e;lc&bOg\/A19-JT$/KS4EGKRBOoP5#6ZKQs7j6G1\pa`sR[!kco0+lD4B %,eQu'+l9/^&8tN?1>\so&8tN?Lc6_.R;Ptr8@R9;'#JL/V^/TcG,L",S)KSCD)7]FKXMaj$.(TJ-m@;V(aU&:o,L&ecZ=V66FtDq %8i#47(aZ!4]JKocJfu>nT\I,t9bok=Cf>-JRXlD(R;Og>'%2b3$1J.o,h%`B$0apSKQNtdP3GFTKQNtd6G1\oaaBj\6GB:5n3V'd %Nu!,<:dVnD-m@J]P[qME-m@G\PRqai8i#:9(a\7t%&JW)S"Z'W^! %g*G`!D3E+'g*G`!D%^lL2G")nD%_G\3XJ&ARj=1-2@2Z>RtRH09p.e4'83$R9g[4S-HVpU9g[4'D6/17RnSu28"#%'UJ4)%d3cu. %UJ4)'d3^%$BTluTd3^%$W0<;gg*?eAD%_G\2G")nD%_G\3XJAJSKs>X2@2rFRtRT4 %9l`ieg*E).Zq3MDas85QAWf_Jas85QAJ1/d1.`Z1>nW<\/dY*>QR%cT1'pKAQ\;0099Mh9Q%Ys.8j^s'--;sX8j^s',pDNOP%*,XFJY,TZ-(#eumODNY.d@$5W-K1Q]O)]FiuFDd7`TS#fKTS#fKTS#haJIX"uJ.=%8 %5mNUL"!('u+<=.=+<=.=Nc_KjJoi\s4:0M-k<0M-kS %UIkU5d3KmuBTcoOd3KmuBT`pK1eBIdBT`pK1e@s6RNrbm1e@s6W[%]f<0G0[RO$r69bMK,-HS'h_'J8)#Esh2F-._%#Ebh"*(5t* %*(5t**(5sK3Hug#3Hug#3HueijrffuF7;^%F7;^Uk+Ih>k$0,;b!@9:-jP_W-jP_W-jPa-UDu+RTH#eOTNhei1#M`Ajsp\ui/n0) %g`sq*K182MNBo7n*%d=I3Ed](*%_e4NYY4+*%_e4NYVpU7uJX6NYVp]7uN%jUIC>+7uN%jUIG=1d3?]&UI@Mpd39asBTZiNd/Y?Q %BT\BtZq)t8BT\BtBcARMO(I]4#Dn+uUI@Mld3?\sUI@Mld39aqBTZiNd39asTTKB>TTO>`K182OOgi7K/:,gap^+mA-O&9N"b1?^-K %!-Ek^q"QNDk\-%hF>QMo3Z97]F>QMo3[uBT*=\/?3Z'.'*"QNDk\-%hFAte%3[uDCFAtdr3Z'+F*=\/?3Z97H*=NR$NWr);*"s0Y*!Hsac39@>3=7$b*!HsA%K]42*;pI)NrB;%7t2d?%KZqJ7t62JUHanQ7t$&LUHV#a;'3o=UHV#a;'-tA %W/kK/;'-tAW/m$[oLC[sk`:gFoLHt^qBLi:e47;6fHWd(m?*>eg*:,Jm1D+6p./d8m1D+6p';O+HR(BWp';7#H\@3M4d$CIH\@3M %4p&[M*m'554[R09*[0QWO(?>Zr#k'6Nt??=7l'.=Nt?>G)_3HMPt*Uj.$"p[ZptB^g*7JUZptB^g*;7jm?%f;g*;7joasNNqFH?G %BdHZ2*:4>9NqQ#@*:4>9NqN`57scLkNqN`57sfoVUHObp7sfoZUHV#i;'/B"UHLrhd2jIoBTJ[(NqQ$+*:4>WNq*H97sQADNq*HI %7sTc`UHF]97sBWbUH:fld2g?-K004bd2aCqk`-q<;&phFW/_F3<(A_/W/_F3<(Da*WZrC(<(Da*WZsnPh3!XW\g'T`h%?BAmRTYb %eIeGajp4gSF!RN@jp4gSF!OQeF/2/Db`P0Hd$SXJK/qAR%d$-\d:K/jR?K/jR?K/qAB%d"$g7s0K\UH4Q0#B^0BUH(Zfd2^9$UH(Zfd2X=nBT?WM %d2X=nBTn %k(P`\k_1sYW(1]Xe-g,HfF)OAF"am4JhOJCP)n-^K/F:`XBQp3 %bJG1^E`ok@,*dj>&udF`OY2oACEtZ<=&DBO@F1,j5hFU,LUjYC!MMkmHu`K7eH%.`>U@g %.)/Agd`C?&n3\*+!\S$kBggoE-#5oH_*dZFCLlpkomD\NYKPX1&S`QE*dg#]Bd;'_jrlpSBd7pIDK;@:k:#RP357t8=X/)!Y"b9B %CLkjJ5)s'2kV]ffn$?EQaL%Mno"g[?H*L5Ff>j4=Kf,TA]dRSL0XMEp2Cc;sNTe>uSP;Cg7,'bP)lqV:8XI9h0Q0A6-;hPtZ&@r[ %';1?KU2;&3_!oJGHQ%eiFL[`<#`rDNO"`B*^fNZ)5D("5YE@c9L/D+(S^XaAMdoYB8A %^*g(C'V4n\2/PbT\Dj%48Fb!B(iX=[YA[4Y)_"sDfpaouSFSBsX)2LP8K0*BAM1?PFEb%;7WbB?YW$Epi"uBlN?BXi3j+I`2l)FF %g.:ajJ>%sem#>FkPUs/q^q8nir4Kf)2_dMg4Y %Kf0PpKf0PpKf7Aa'\Z*^'\Wh$$>ZGi.BJY^.BJY^.BJXAVQ`MkVQ`Mq;d(C`VUS'@;gK[a.D:j;;gK[aWHf^V.D:js;JIFE.CBb^ %PhJYt.CBb^'\Wga8o5i9Ph$+3$>Y;;V)FK&8o95(V)CZ%;B*_#V=['865q(q7RJ*q7`-/g7d5nCN5?M77B)9.U=;Xf7A5\PU=;X<;/./.(#,b3FhK:OJ2;9aA@1- %*CI^_BnQk."G@.u`!I7.80V;0,>L3X,N)cc,Dg?'7Y%t07Y%t07M=QE)?J^3)?J`/N?l/6)^4(:N=^$X7P`i!N=^$X7Y!F",FNGV %7S#I?,D7#;Oj#^c,=EKQ&Yb9984FQ+&Yb9A#gl+[,bp@U#gl+[KQNtJP3>APKQNtI6Fp#5a`O:96Ft,hG62^07M=NjNKA%b7Yj!: %,FNH!7S#IQ,GZ9dO\@\`+/Bj`&`Sf(8EO,i,N)d>,N)dN,Dg?tNIYs+NIYs+NAS@H)Zee^)Zee^)bGDbD$54oD$54oD'\X'Zk;dZ %]FjWb]TL.An4"C:ToB%kToC>5Kf0"LKf0"LKf5)"(YT-#7r8BZ$Z..$0"_c-0"_c-0"d=,E0]!F,@%'%!l@r@,>Pa@Bd=:n;AsPl %bs6>(fr/G!-4@Q#U!1tN?lSF8gAjkV)8=q]XG2F>R*$pCLnKf,#J=(.("Eu!733EKXKAC+=Y %,:$QK2+#_k=]65q*2.^Y>^\I*2,S?("+a>mu[$$Jr\Oj5t>c;K.aMCJ1e2@J1eKs"M4(l!4qYh!4qYh)X'L,!U2oi!U2oi8Yc`2"Ji*J7R4Q37M=rP)Zf3? %)Zf1Q]ob^o8oMX>=.tTRFHtQN!aVW\!mjq^,:+m9f1$D:.^]k=Y#62>kpj*'d^`lUNIZ,9h?ZYRQcQdo:KSj$F1N&aKT`#PTc %@ZJl-`Z1fe@ZK"F0h6")@h.3`@*Z0BTH(>$NcNK9Jo]4-83'cs*T^[g"Qa$N"Q`82'dhhr_<*-Nj^=&Nk1gm>-jOT7-oX&9.HTcQ %ABN:=+m%pI&9IJ5''?-P&9H>jLcK2pR<-kIa>mu[j;bRi`&V!Gj;b96EfSjEjrCc@EfSiZ3Cdp3F,nBJ3Cdq>S>/!*3>^BT3#C9S %3(Im4@?01M-l:_G-l:`2UKhIWTNl.TTNl.TM0#AMJ9040LcK2p)0=:sLcP$lR%lU'0h6-bR%lQ+bY]>$R%lQ+bY]<&k,=8MbY]<& %k,=7NF4n-Nm+EA"%!E%\4(#@0kF$$7>M39\3s!U.B<8Y?H*"J?-:"J?-:,_7SD&V)L8&V)L8OT[^Y,NKiP %&V?%s8-U*B&V?%s#XCmq,_M-.#XLsrKV5(tP!MTRKV5(t6I=*uaeY[i6IO7#+mJ3MACA:5+mA-L&9RP6''Q9R&9QDk#Wc]F)0F@t %#Wc]F"a&TBA0Oi4fW7_lR]7_lR]7M=m_N<"$nN<"$nN?l`%2Zh3W2Zh3W2pu+eXHA7J %O@Fc2YXTURO@BlD65jjbKeieOd2>N7$Y]a&$Y]a&$Y^k@Nm\1E(Y/j'(Y2,D*46A6NnOaV7r9M-NnOaV7r8BfUG\2P7r*d:UGYBX %d2L,cUGYBXd2F1gBT6QB;&^\=i/J:foL:Uqk`([DoL?n]H6\8de4.M=C*R7/[?8ZmBHonb[1OUCg.4OMXUub;ed)jXD'U?dg'AQd %D1mkC2Nf4Rjb&Yi2F>J^)p+0LD$5q.D$5q.D^7V$]FdC]]FdC]]TEE/cpe#Gcpe#GcpeZ/65osd65osd65rLX/+!Qh%!(/%;O0=+A)D[gQ:Un]i28OmV#U^M#BU^M#bOcJ-$5Sr8_5Sr9J!aU$q%_C"V!4pNH''MY$!U)ih %!U)ih8Y?H."J?->"J?->,_;!4#WNXW#WNXW8B88QNAT!>B`t5Ieqg*(8L'(79cA$(2.m'!CX,Jf?'@an]-`L;GYK)J`,!d,R+JDO %5d+<8M0dZ@8A3A>LqV/)1A=*S+o"AC!VpDgAFbF36M,sh6M?*jP2SoH,iUpg,8'+T)X66DBHn,P-*g[H#B-CGo\b]s1@*dfjKe8E %E\?\38>NQ<7O"+O2U\G-Y)Pgr$Z..]G0i^!aUZlmPjDe;7*,qm86<*L2A.;tcYK7a#Ap9;fKo=hMB0'dW7XBTkpgl+7Tcpj2St=l %]ocR*UGp&Y*PE'9m-'G)RN8dJf'K>pY\$CB,hMC]NA-Wo2Spl'g.77pW/WLRUGp%QJ:L?58I0.h#U%d4&Q#]W,N$i6jM/>bU;_.qKsEV2bK=!U)ps8L:+)hrU'5`]>V?W4)pp_F^+CLg9ISa`*7:ZcginP5 %Lb@0!%)n?#%f!a*+c^5?3rIE,dFL(jkHHX\o[4eo&\ZgNmkrt<]TLUFCP4W%qNZ^&7RjSt@3,)37erit]U1XPe`h'fiWuR5=N/5k %<@[^UM'Fd)?*eNhUn$5e_3`inbO@t*5An=WO`<$%,`dQAN=:8o.!d+aU6OINhT4W]eZk"(Qj1m6_]'J@DJ=>?KAZIEetG&YkT%mU %M'I=Oc#XOgo[p(e5]NUP*O*C"dHaBYd_$0+/#mG$MBf]r[_7MB`Qo)=NYJ,#L36`@d7_2bC#V\R&1kb^d:\Y^*>:q45N5$Md6@;O %M7>Mhn#uC2XCHrK?"R\qgP0R;ieXrnVVq>RJQ9_QfXqe:]Mkn@De#[lY+jp3*WS5;P2_9=B9G0,324IP:/N+mLg>,%iJgCWDM&(1 %`%KH]1WP#k,J$PZ#'qN*"l+1>]Fhj&V$4^QT%/9ic0g3RECAQ=F,D2gR:gEH)_uEO/tm-'La.5&D5'R!XDR)Df's6>C]YHe&T)7c %6uPJ;J9o8&jH[VqR^%m!,PE&2J&LJN.F?Z7iBC(fZ8p@,'^A5^'^A5^'^eMI;Rds&;TL)6;TL('9-K?!9-K?!9-K@,QGOXKTXm2t %4G>lFnW`GIGtN:64Jb-&GtN:64Jb,+TMciQ5c$S0TMcg3;!F!NT[Fi(;!EuK0s.'4^_f4a>ir>)0+Vr!--tY!--tY,fGC$!lTdW %!lRqY8V@J&"GEO8idddgP5%Lr"F(<(A;FCemZ/X+Kg,XOKg,XOKg1ai(B+U/(B+RF(]HrL>R2St>R2St>R2U3E$:<&iPHZ;iolFK %_M(5V_M(5V`).XKKF<>6KF<@,[!Mq:IejDgKg5^VKg5^XKg:e<7tH>P9A;/?;'UHen#d2sOlk`98o5p.?1.$,!['M(">.$/t! %oLHt^qBMDJoLHt^qBKMjrK5;`qBLY5"VO.^!_J+d"VO^n!XU;GJL"0S!XU7[ItWoY5E[HcItX&]5=3N?+$$/;%?aCF.O:f0'bXE) %%S281&d^QgM'R/&&d^ioM1hOs7$9f*LP2=q6UK/I+j$MfLLc@9MKXbcN*g(c*"n>c,a*hlO@Xo5O@YmaiK,>; %KgPpqKgPpqKgV#:7u%5O$\nkh$\p"D/fYM>/f^#tDV/M18Rbsr,[anK,[anK,`-XeOZ;[D+T^oG+\AmGM$1$jM$1$jM'UK/&d_q^ %&kQfPC:/9r)mB^,"L&8j"L&8j,f,KR$"91/iP,BnM'U!!&d_r9LP2n,6]tkJM1i726pfU),0@3e6iu)i+X-7:OC[(m+X-7:OH=X- %82BSrOH=XI8-h:L,T1ci8-h:L,_R0aOpjEE,_-mU'%2dM8Z!LK'%2dM$#)nbjHOhp82BS2OcXb984Ygg,aiiJ84Yh",buGLP"[rp %,buGL'%2da8YR4g'%2d]$#)nj,h"A.Otign]14Wr,\$L='(*O\!U[`K!UW3!8[Jkf"LJQ!`+^#/8YTL8,bQ/@Os-^s]18#l(ENlr %(ENls7unqENZJL@#EOPBUIUJ]8!/J3)]G&%ki(8&lmS"sG4\<24*i.iFqdLR4,P;:*CZ,"4,P;Z*CZ-S0#mb0XO3%P$#)nlKX@LF %P%b/`,\Yf<_-];ZOee`m6k[oX*_F_]7,H@*#E^9F#E^9FB-Kpf3f#%l*BXt?NZLc(*Bb%@NZJL07unq%NZJL08!/J/UI^PV8!/J/ %UI[`(;'a8fUIYI=d3Bh$i/qR$d3Bh#k`LsLoLPRY%OOcf3iF=?]#'un;$WG`6QKEp5TOBu5TOBu%X!k)!d0Sr!d0Sr1@!e\"R=p. %"R9sj]L*]F&u#jg#t[XR,a46@#t[XRKVYA:P"A03KVYA:!n,IBaeY\)6IO7-).JL'?M^lY>S<3;%#Pqe_BhdL$^YC[FPgAe+fZaS %OsJOO;sYMlh*dY6W1,3!,h>\S8Xso:>nXAZU.^YO2c1n&lTup!lTupiX:(F!X:(F!X:(FAYqBQ"YV'H!YV'IL`&c$dA6moD([53P %af'hc!n,IB+mJ3RAC==%+mCD=OE?^Y1@$:.,[_WtP!C$mOq)VR8HO$F/l;k?UdH/-P!C$uP!C$uOq)Vr8HO$r8HO$r8NP?e-6_[4 %Op((.P'!dX9+n=Y9+nF0$_[^-$_bLI(HtEB?2,[q?2,[49_3J#,ge5l'$r7Y'$r7YP!hD.,_01q,_01q,RJW;PQ5kMPQ5kMPU+n8 %:u\\eT*2A+T-V6*KG)'QKG)'QKTZI"$70(c#UNk!Kp%,#&5%Ja&5%Ja&5!T#.$P9cBcDdf$72*_'M8?eqBU_7I?G"#$71?GKbD7_ %6:lnPKbD1]4pbpnT-VmG4pbp.T7jGD:Qf-VT7jG$:dW`1.*8Qc:dW`1-m@n)P[r?2-irVsP7Vm/8M]SpP7Vm/8VfG(,c@T9;3FdH %V1beB;F8mD;j'F:VhC_<<'nqt.`n3U<'nl-.O!t'PpFYk.3[j;PRqnX8i#PG.08VK.08VK.7p$;VZ`LtVZ`LtW?cI9U_7W!U_;iq %3$jE&iKSk6iKOa*dGLLX`49hZ^c=G%^g&iF$$5'iJ90\6J90\6,gM*C!mZL!!mZL!OuPt2`%`''#r!/j8]"_'-,t%-"J%('!dO(8Z!NA'%2eL$#)o7,iano %$#rJ?KXddZP&LZ0KXddY6JTs=ag__^"LniC"LniC,iLAg'&YCT'&YC\P(^FY97XVc9,r07PpG.=j#/KsLJ/KsQ!/]kX5[tMO)\V.m/\KiCQj:X4$j:Xd4jH;pEE(e9cE(^JN %E(_t^_CYfaRTfjc27Fj9YIPs0?ZSk*^Q;)$rL-smr&)%'q:FDb"MetL)"5j(@D#+>,fb7R9,R+T\p;(][j23+FA&"R_C]2&9=H20 %[4%b(Xef:>[$G`(:2;#>+KM>C_@dpGP$Gl!>f%*pjV!mK.$s!-*p"$#n;u_8Jk*?s=7@W)Y_#BUKG?Vl-+SU4\KiYLD&ZftK3Zii %n0"(%L'P15C3X\j\f)XNP,R>*/r:JfjH?[##J#M%/_lMFp>D6Yd2q)+M"]bm7'm3.,Qj-G#ltl`#mhGh8Od+/-"J.[&i)0%Opo0g %90beS-)=qY,oM?oQ4S`.QB6dYQCO]=5HnFf`?SB?Z<^p.VHUhhdC()TZqEk6c7]^Q0%!"NL*!]p[(T2!G)8-#`\gFBdIPmOcQSWg %4U"d/X]@#jak^"O-!F!s[ua7ihDR\%;7U5eBsgT9+0;n%1N#ORoau$O5%ia5&o#\"c&jrq7&r:.#U#I9!GA#k0$saG>2tO.>V]&l %Leo^d[NtT_fHoR"En^h+7Q8?n4YJ_p!\:=(8R:\dS""oZKjNL011R;=/pDM:JYm&3`S5Vi8/#96:EaH[$jJO6)A8oV;3Q*,8/27/ND %kH_UX<;gOs.LZ@,8p$>H$`dgV`(jJ^dPen]YcP8N>Er72\G4H@X(4nJ-DOS8APnGFBU*90fm_p&E-6Y]iP7XFp8MWVHP7XFp %8Vg3q,ak=48Ou\C,U=d\P)N6&,XtT#e+n(XS)N,3&>c7]fuaMVsd08J&6jVZ+!gpf/BpbCFG3,aE5P83e+0$#%4#WGKHrJSf'GYRQSfZ42d]Cr7HJD-/'K %D-/(!%>tA!@?FO!@?Ef6//%0$78iB)70;;@OT7,S2Sd%Z>9s,Sb;i,TmSR"NFl4<6/L15WLA..#17>?NQ',LHbk$n4+thn4/!KrWnUL %5>iAS56Bm77pm>987`e?#`M+nJT1r@'ljR*5Rr?5OM`0>P`n<5jR>Zi*<&K[*9mcj6QZ>LkT^g_kT`?qlpIU8L@Ujb*:aAs_]Ai! %fHV,OfHX3&HN_K"O&X81O$G_t&L`Du;CRAb,0F>T5WS1n8ic5M-ms?EaC1-/aC1,03U@>#LHSNYLHP_"cps`KqFI;"p'?o#*eA@a %,9J@i4]3_a4Ta`L8"^jq8>R="#aE4JJTBBfKlY6Z:_%aRarugFb$g?eEl]J%%XFjJ%XA3"+celKjH3%pj:Neq49FW+7k3V^8"^jm %#aE4JWKb:A.8*oMc4c;W*hf+6`">iVD^6bZDra?t/Xp$:+/bdpOHVWoU7AlYUth7]%a'Janq*CEObB7CObB7COVd((N[3[2NW;(b %,;7-[)bJ2o)bJ2o)l]'cnr]0#2Nj;g2Y*T4[#q0>g4pFS1hl#>3CtGe3E[Ru\[FOI8NBou8NBou8NF7L?At(*P)PS_!oqWs.c\lF %`&Oh1(l'tH)2C'Nj02"'*7dZ7*7bCW_\rPr=o@XH==YA;qkoA;qko %A;sR,8K(1=8K(1=8K)jt:=]],P;JGYP;MhsS>;98>Y$)23(Y>J_FYY;_FYY;_FYYk&PgbF&l-kG'!>deG:iCDfuYQ'g9$K*>Z`3^ %:;R9il\f(RW!]+\=p]s;!o`W;5TIL/73'#ILr1#0EVL`CEVL_3%UfL[+cKC?+cO2rKFopK?_fFe?NeC-Mnh<"Ohs(W%iC'S!oqWr %.c\lE?sMB?&m;C7KfI0u&.VnI_I8@%_I8?f3,B04LFlCALFiSfUl-MXUl2ks-X?kn_:l:fL"de)`5rcd`5rcd`5rd?+\oI:,#5R; %,#5Sf$ZWI@&ol>g&ol>g.cY&t,i`En,i`)%M-l5-Z:-8'\nhrqf4Bj?\\;\q0d5.[MZC:?>6N#ifcgT??*X`tl]O\e>aI!>+kL:` %#]a4V#a"A874RAEaXrcGjLSk6+P.ot<604(,!ZWW!P'geUdD6-(GT#&&Q,^S'7k10Sk,\_5A5/t %G^0&rOR)I*.ce0'&Ko]O,dG*G?(OT@>aHf>jLR_k+GV@C+bqHIj:F`_3BWE23I)f&%Sm5IaV-+Z6h(.rBHeQ/9r&sC9a&D"I7-(, %QUE=`O@4U=Q3`Si&ugu1&cm#T,!ZW2Ud>Pa"NY_",#GF8'<.5^dR6L6*gR(nl`ro.jLQlS+P4LDJT4t]87c%m,m*,aHc=iqf73Ef)=.#ui%Mml:pHM!M?74sCJ0U`p:A"N4`*J@MgO.c@O!!$%:1Jn6J2[UnMDkYMn:i&0]]"WF]]"X]2uF6^L*':nLY;decpIdQH:S2ZH3f$OqhS,m/r*EA+bp%Wljs/P*Duon*B@mm#[)aljt"h*WkBK6OMkX6XUmW#`QY2q8bP^ONKQL&/^0C!opLP %.cmm%TH&+\Pf!t[QpV>aF3#M4%QU=o:3MFILE$BXO@(M[O@-f'EX8%"%]Pg_%KUXl+^bd?Ugafo"O&$EJ2utXME1#70S^YMk-.5L %>7;,+jFr+E]TA"2]FZcP(Qt/L(\5G5]TC(eQ7NNiaUbjKd>bjKtJf].g4"gKg7Z*O@m'g9^"Lb$3>0L+Vf$"+[?Mf"NY#*<6/L% %!'.+l+GU\0+bpd6jNp5D**PmaS?*8=LD9mNYX1N/0!13B\[4\r>Zr:Y0!15X\[4['?!8D50!14e\s,Nh>tQ9U/u=Y%]4'<`[^699uqbBH`mCP\BDrA_BGr>*PK4G3FI$!^0ap34b %?a\/Zh,jCpfmT+ro'3rD&!FV-#pD;s-R%P.6mj-'LZg":0LR91j>B=Q+!cX*e=C$$:-M2hTp*W],BV@"EeI1KaD6H(3_5:XXaPF# %OH;b76ZeJWEf#'l3UaTfjA3nYW97OK/92+Ar4,eL8.6*bV\*TYb^P7BqF:,YYOmUUrLn6pqL^9g0K?eQV;I;+>L5&:e_ %QSqBg?eQXL%ikfLV%-DmQSo*L9H+*9V@E).Jc?26+A^bKmRia1/C`CE15PV9c;eSSH2B-K_VGC#%c(A>M"f_/6NsapHCaj>G,'k<=kXQ+Up5.SiZcbH(kSqlD_M"c$Z@^/$@lbu9?])OYR`B54T %Ic2o8ojk-;L'qJ((o]=ZJliQF6SJ6L778G&I^2FuC"25sgD#bH1OT6AYTpL+Ns'm,.N8q/7O3fN#5(Je2BmdH7ei6G1(CIcEnR`J1H+S'e[6A"=["&A*/b=Ofu4 %FA;^f7gZGMX,;]`+ngjW\!GqH=J*Q;>%\qd[>XL<6CR!?*\IDPQ`GP+cSeh'&USnPr[,5#jX92DfGeclS)T+RCM""pS.L#VkEZ9G %r0=YG\L"'2KX;USOQ;'sBDtA>OV?^prciQ8dTdj<(]^0<(]^0<(b5iVG]aDVG]arWJloT:1])(:1])(:1]*kE%3(XE@N19S77.NS>(^f;nNZdMAK09MAH=i %h$X7\GTd6fBHb/*/HhH8KiFG6K`G%c+g;Y4Up:[d"I;Xf!Mt#a'r?-uTG0$^Pi@BrPbN;N;McQY<+8B%.:NQ*brl?.W$)nOW$-[* %2$B#8L(o_YL&b,q&3q^$UiI/*"HHrG^er=;$<#(Z5`-JC+I*l9!bnSVE)^F?E`?YlMka^8,Xu@",Xu@"]J(fk,V^c),V^3LaGZcj %6^"0A6^"0A6U"<\1Sc]70a,K>L59ho+dI%l+_"\i+V5,8U_6F/#_9f#!H<9,'l\C@!"L^d_FY08J3s_GE/5Y;%Paa\%P\+%+bg8A %nj4h`n3Z'&]FaQZ0;R#j?3kMf$NY-i+Ven9+i"OK"Lqlq<4H@l!&s6UpkBeepkBaihiL4`)feL2gUROfSSuRm!)@Q*jVr4GHp\AE %E3_h\hloK+)g2L7_[`Yn6g]DBkTKp94er]#4TrX`5"%@5O\.S9&I=.7!oX\Y$K:'$!''lf!/DXo$&9T(iUB2W*.CF)*.A0H6P+ff %#U5OQ#U2STIL(bI&#kB&%tS`q+YXBjUbWEE"NJOo!HIlXQ#R'R0FgAO`Z^.c?lXVd@2sS!N'e*fj01m#j01nh391W!LE'2@LE-HY %YX?2GG"BRlFpOI&%fpb8+dI-4+`IoS"O<]r<6h1m^cD#uE=P(+JdsjFcs_\p3p_rc3p[D[LE-H^YX9o+UkjO^*"c#&,>qBo,6I.L %6pR:_O[;)C&P.[$!pNNL.d9bt+#:6#UY_[uol3$K)[#TfWK8HdNdM,_tJM1E1mLJWaQ;Gi2r!p\-# %5TQ:a5ol6sXMY[%F]]iQF]]il%SHrU@>Rt7@>Vc\1_EiF-;n!%-6h$_&cm,W+r,6&,+oE="Opk:<7G?5J3#4n=GJ2#=be=*ld/%- %*Lb%SemXCLeffmc3[>#%S&pg6P4ll-mFq!3$PR:7g.E%LfDsaLql%s&Qjf6;H\c#!pbq9?lbD$AK?p>X@!U4lYo6AlYo7" %*KCE,_\&lL_\%HBE^W/5N^uSZU'Rj<'M6lt'R?s$b;NJ,/khBqSP50g3f,'&\nsad=VmgR$[!(N&p4gU&p4gU?Ds&9P,OQmP,OQn %nj8m@O^t"VO^t"VOVd>ZGpM^OMBqM`MS*%=DW?O"@8JOhB8JQet1.>N>P:;ZbP:;ZbCUk($/`GX`aiQQ2+pkh77:)LJ %/s;ajafnll?G8tl*52]K_\W>qp`]l`kTYNe>m/NJMcA,uMa0=F&P.[0;FuWr!pS'#+Mb%UfLg+cKCK %+cJ[tgkSEJAYaoQap=M))1ciW,DC1U,B+-&"O:G7<75365WTc-#s&qK0@7fX8^Kb.5UU.("Ze(WJ54*TJkj>,$Zn-n&p,lu&p,lu %?D*K:P+\!nP+\!nnfjWhOX-K^OX+5UDK7$D`^h6n_?cr)(_Q'&74RTl7>*^D&Q"68;Gi3&!p]8D5TRR0730)JW'_C&FU03,FV7.d %*Pr)\6Puf$6PoiH#U;YV^.:[5^'LYf3RVah05nS:YP9<7%UT@giJU[d+cX8uX:\Qi2,[R)CBW-qNIX'kOb,Wi&Q"6>!pYk:.dE*b %5TS8YW'_K&W'_I(F\!aM%Vql7:=]]H_]")JZ:6>-:d+k"g'F?=)l]Jt)Zb&k%tP41Ull4-"OnTTJ3(W2Ji^OV:kpt2lL77mlL78. %*Sq('_],SV_]+/L&k>2-i^cKYieUDYDZnMINE"?bNBfP;&P.[9;Fr6S"OQ+e!'7cT$9H*;5_h<#kR^6JJ.?LnJ.?E!d%QF)FCC/. %b[HJ:F%@N`:=;\0*7bC[_]")H="NmEtLiQTBQ#]tO:_%7Db$g9/au*TRT3WeEs"i92(QTJ(gfC!I'3TZ^b&Lc8lNYKVnW?Y6B8KEA&:$P9G>RPZWa>KqA5d![!WK:mn7t=j.3We@\?'#,u`^l"9fBC51 %E_Ysm`E\W%!Toj3&MVf^O&X=\aWk1GpE@aa%;Pk*kY!MRb'\"O&`Z %4*&'hoo[D--@J:PCU-G1?'@EL6.]Y.!4jM("OK$Z,8G;pp'@I0Z:?$CP@)L %lsu1X3t.8Z3t)a0LI%*-P-5`IUSYbah!dZ^;2ij,VR`j+b=bq,d7c6Up=m>.T;,;_BG%l3[BlG3[>?3%Yk2:iK.$g %iK/RN*"l)'6W-d:6NZOl83e1*8O]0q&kIdG!pPe;5*.B;P(L8E875^Q,_B;?,aEOeO9g%ZOMJIB81O,W+G"cOOFXu#81O5Z+G"j< %OFY#D81O@18Dmf(,_.N_P"NGf83gN3,[qi"8S)6I,eu&B''PYd8];bU8[e;&OCVQk#0EpJ-]KD+HAcXffTShrC@'%eaY%FT,h\rX %7oF]@WbY"X_"QlqT$%*P7M,P%/\k8TO/m-HU&i:*rPUBP!?;92?nVX/.2-,[5Rm8[>0?Q)*CMPskC?P6Cl]8Q#SV-4'gn %,_:J[P#MR]8HJuK8RPqp,Sbp1P(:AJ8`4!V,Tf;Hhm,hZKg53-8[b"u9pNZ\],-fEZO_=nP(u]9`AhVT,hBcAn!$DP(_P@q671B% %,\Gm+0%9,p]=gsPp4=eRH8LH,knM4@I[s67$8p0B8fAjT1R5F5UBp&n.o[M;7)>YELDe,$`Oa_tXE %baS"`&kSZVH.`pp8CHjBAUTsX8Z\'1O!TrkqffZ<8CE+\q0X6$Wr(.3RO$Igf[",lPT"%GP1YCHcXi8U>.#H9A.+`$^Bp*7qc.fA %La8HIOO#59CfMf\Ss6nurE:D%D51hjSndrr]8o0A`M\3u8Q%j38chO\8H:1l8HgOq#p;Y`!Mmd^Q))JHOAmu,P#O3Y,,n8!`+bSa %8Q2$&0:L$/8XddI8XddIH-oS<8^^Qb8`E]!aU>"E8\h:< %VO/XE'U,?0'U&Zeas;P7Qm@rnQmAn8-4)*>,cN32,QXa/,bPj8UnSP6"I.%SJYY%m.S)9c!9r3)J/"3CJeXCOOCF@Q;G<5TdPOMu %dPOMu;G<7jd54FHUFD@^UFD??OJYPmOJYPM8.eEC80sG7;+qT^MFg]+.[(!o@Zl7=9Tk919G1bJOT^V8,hZKJ=bn>"'TiNU,*I>H %BUU3#EN,+WEN,+WETrW#`hcLiI-lLiI-l'ZQt@&r]1'&`Q\6.?$o^7#Xd$7#Xd$j9+Gj,Un[FPsgR(PsgR(Q_Z;f>nSkEAJ.imAWfBjPY$Ng %A.gSO9Tkd\,QVtR,[_+GUiHs/"O:G=^c>)OauN-.3/:',k>4`"kYOhR3_U/WLIkB?LI_L4&4p7M,"Z@:6kW=O8-8&f8Lj!:8O+:? %$)j%Y;FuX8!pMC1+<;e#,on<=Ur+I/FI4QmAmG %P6BI1P#U#+P)+7J,d7cBUp(>k"P--i!Hj2D'm5^P-!E2Z<.niaU<5H8J6/$8J6/$8RA?Z %8Wp$98Wp$98b,3=9TiqW9TiqW9Tg4XA:Z#lA?GG*$tu^_^$\$99Vc699Vc699Z05/kqKO*?kf_6R8Y(6R2\SLa7K\OedR=OTa$>OoRO:OpX6D %&jV4D!pD=0.d/QX"?Jp`5_hm.8V]hO[1%2N%[3]]%ZpnD+d.@:7$>\R6kWUW8-8)g8Lj$OP(5S]&l=?S;Gi3@!pVI2 %5TM1C73*]]W5Bk]FdOEhFdOGI%[.%F@?OU>aWuFZQm@bg-:n@]('pSN,QW"S,SbEg,_0e",=%#U;FuX8!pVI25TM1C6!]p)6=$$* %6=$$*"a+OB"R8l1&aN=?.BH1)7'&a$&aE7>.B#n%7&\!K&a@^h.ATV#7&3J>7&3J>UlZ(M,X@\?M*RCOanE$^,1T;Y99DW899J9; %kgC_*TM(P".$l]G.#1ItjcE&sE\^4:*$tuR_^)4C_^'eRUtnj:Fm4j:FnU*$P]R6R8Xq_^'eRQm>KPe]M@?OU6@?Q.$9G0%78Q%7/-AaFC-AaFC-:u$YRO!Hp'M3tg'M/Yo;Buk:;Buk;;C!]]99EaX %mj:^@JM'Z[!kL3["M-E]"M-E]$L#n`$.>Y@,1<;Y;Fm,uM+EsWM+EsWaTp7j8Q&*G.Z$]_.Z$]_/kKJW\g1`jas:G%as7.6.?b$\ %a<\P2R3Z2gP6BNHOoRR;OpX9E&n$Jd!phU4.dSi\J/osCYX9_9YX9]KlnD"]*@=@/*?kfo6R2\ULa3^YLa9c2+pkJ@,cS"8,QW(E %,RHPh,VRfl,Y?X*E*9E/8b.J(9Tl3B9Tl4-`frocSP53BSP53BSP51_m:;A*m:;A*m:;BmBI=05Bd])iBd],*76?n_8\&aE7>.B#n%7&WbB7&WbBUnB>7&tppP&tppPP(L8%8HO#` %OpH1ZOqcChP)+3/P)+3/P'eD.1._i:rL@h/Z)?]-WYsG=s83^frRNLmKk'a@hpHR?o6,e4Yu.m%m9O\VE`XpX1;f %HteaCntenZqU-X?IAeEVIArA8IVFs1^GJLhrX_Z,XXB5VgNjK(?>Vi^,h^aA[]-MZOlY'FP=UjBg(6i]7k5RmHF.+DA;=248TncY %P.Wi_@?P/N<[LBJh8ppf%Gf,Oae:ea,WTroPN4TC-^,g2m\5&l,Bkn7?6a["5]Yp\-:s6QaWu.kgrUh`Oh9D(7dafM]S>ibP2t8d %9TgC-P=\ZmmP%3L]>Gn&ljf5TNnn-,W'cJ66;%iOUpfn,8SI?3P0hWE,UrL]O[StK-AhN,9TfImAWhk"Bp+:&b9SMB>UE#r0LZU/ %E/>hDJkI@$#+%k)%PEn)&!a?r#<#.iX8,Q]9"HCkop8b.XWGr7B#=<6ZMHBn?:hU7kE1&Oqdl%:/A$EN,pk"Ydk.\tli#GthPq")R+)Gl-jS<"U,:le+cZQHNmHACe.X@%_h"d^,Wr?,FXOtPk&t^N:@7n%;nnbT.lfC?p@:E;RGYb/O&cQ.Hc+`%;XMfli %%t5538fmD=rEdH8So4`86/5SHl=DcBN2O.$Z"T,.Z'&HieKKcQ,rT'ao@RMOcrJGs7AA;`Ld;PdQ2GCL?\`gW^h!rA+ddApMq_:3 %P&;N6q`;%+hle8^8BNWkDl<>+A=2#)nSBYh`4C8\ATD(UQrk(VS)o`@ZMP*S7jeYQ5G&.,K2>6b(BTUr9Qj?^g:LD-*p(j)9Pf/C %`J`M*Z*F6*ba6TaPMK-adO;BXCn?!.@FAG$ba0Jf0A9dFAg'pVN)32!hqO`Z07_4pF?`LA4V\Xb`a0`$'-l6X-htH^@e*%8X#ckZ %em5`^P<\m'Dr:QVqk*hB^](_9-U2`N?LX57S*a;S?_aY5VRmd.Y9*c %!eMk;!eMk;;@uT2'+diG',XDSPJU]7S%rFr.#Yq4;;M_IOg5fT,paFfPO`0:;Tb:d8jX@:V*Z"@,pDVA8eMscj[ERAPU%qX8eMsi %V%=Ik,mc+O,lrsincCLKMHq^8G"@<#nM_tg'`M]u'Ce"3S;=p_iM>s%l][.><&b3^;W+@t2[c.3^2!s>h^i_Ek_k`NqI69d?`]Ja %?aLO2Mj=EmV57/dU87is]G0:^QW!(+QNDU*;Necb;I8u)0*V,C91enN96n?4[$5+)[$5+)[$2ARV55GajeX5L_b59K='eLn='eLn %='c6tV6u8K;L+%a!q5VVi#Q,rjW.ZbGSaNjZpRKc[$-dWm*JX\*El'h*G,Y_$T$m8fMU\)YV'^]Lilk\7'+QM-\Z\Gj$]ul)CJu7 %78=W`ZGq_t-Sm&?-T0uh3lrhm3UE!k*.#bcF8.1gROQ?=eT^kDiL.\0m %Mk,ZH'K[bBb@2hc>o#L6lE]&66!Y6U&aH[S8['g_SJ9^fXV8Ngm35r)[8%(q0N80:";P="TMf2G6Nu%LW5(G&PmTS]'jufk!pi`_ %.dTu2J/sLSYX;9eYX;8"m4_M4*JR1_*JOp2_b^AX(b-8E(b4H=M@-^X;5q&m;#tkh.c:e*jWj1i<%@<4<59N3$FiH#WOP;m&ah>P %!$6ke"WiC*`5>E&GShoqGXs:qc_ZkQortdX8O6[K3t_%hgkh,Zj\?0RZJ::uQfUtq]W?=_R$Zo0`&o<1KH?H%MgBUtM*47l`#beu %$[YcO[ZjaSH<;Y^H<;Xg4Z&G"Sii8SoFP"8HC-/g4]I[J4\V,o*i_h!%p.j]4_0hR?Ih7Oos4!W_&d_p7(o[K,3iaqP(XTJ4#<@[^H>NI+'YZ31HYZ8I[[L1[)%eccU7S`W2tc76/F$(6"mSqdV,E?e-t&)K-t&)K-l%)n0*-Ea5S<^gJ5WXB"Ve2-]+F\7J5WX"D[#K! %>=n0=\hjS;nl?BMnl?BMm]F-p-Z:<)-ZK=R+g+f.+g(f.`"er#\5K#U\0C.qX[#%^PtF3P'rZns!ql%`.eW:3TH<)"e<@C?Tng,Z %oFP)S*obkQ:a:[(/YTr"mVec<9g0]5WoesW/&5fWJAFop"Wa@\_NiaejCn9UE5;cQh=0C]rZueW0d0R7(o[W,3i`*PXW9eLEc"lYpB"h %=C0KEA4c&pZ6]*>=^KauA_GL@8aN.U<:!1d8a>9>,kV^O?IZl'8a<"T,kZ+Z$M@4uP'XVh8NgUM(\P"8P'U7J7F]Mt."us]7M59u %0T)Mn@?eXA/8?BkARUg2?IhOobfdRG@c#g-0JDad'^/u3LjI,n:_/tj;@f6#l=%"a4`$EV4_tn4LX#tpcrhjlcrn/UF;Cg1c;LWs %c6DPqAc[51//N&"24?'[qln?Om.J=!*0$Lk>XML_%i;$=P5NO")$V,7@XKU)`^7`u0a3%YG!Um;-)<"L,"9FS %]*RD-M3L=h`0R!+Pr'Er`5?Ai`'\?lG_dp_&$_rD&$Z;t@CAE`ba(j`bSH"if`L^u>:T1t>D,,W(79m0;ONh86ZN3S81kX(P$FY$Opfc,EiIPUEY7t`>bE-u9;N\i$e3(6JU0:.Q$PDB:_1YOl63];l:H!sH:TYR&'<:T01?"KohpIY:h^FRoINUfYaH&qOFmFcaq-]-IQ" %?#l0*Y01UF:U3WRnk"#H;*N)SY>IL*0%o-Im?4S9fe0JZT59j1rQ06)et6cFb!Bh[EA1r?5a\iM-"4qKT[78:Qq@i(VX78ipcM^d %_Sr2K@@Ag6KPA$5_DGPK@@AfuYdEYEfQ?r0VG7)W.PZGLdsq,4s24hSrm^u%?iSZ+r-eM?:]BY:ru]!WjM1`jO8e-'s53kUqg\Tp %IfH%3J,cjIhZ&Na:U\KQ/3$:?+2bEB/ViF8>aq'XZi0ed56(6SI"HkBoC;GPo^i+Z^MQ48V8rW/T1/e<[En:fVZ$Mloqt?V07W:& %j0rA[fq664s&0h$Frqt-A+Sm!:hbuR*UhH#HJZ=PK=h!I?-;?fcR\%Ud/OnPqX=>Qs6QX*>bsZF(\%@umqcoC8*c2bBhSF(*jP$k %of>U4H9^hckBOAtflN=s_hZ^4bArci0'adDkA,4\_Z,(J`t;I,ocu]FjP'2N4U^Z" %F$.a'6C*:,cLKTTZuLK=1,:i[,l8=U8Y"j#SRgKWii %oBB?%Z-DIo>BL%=U^a`adbs4,T0N7$%F7/Wet\5N8XbQ[RD\ag/;NWaoVF`'7E&$m[[s&OJ)AWW^[3Dp5L66MFaEbjbtL?'H69cI %%P>A8pM?\LjquAb;uY+XVe%u]>O9aXaUY3GD;<$0o"8ICs6q*(Ac'0%44;?aAKk9org=-:HWJQ']O<]k6*_L[@.fRb?&s-,FWHCej&sHW@5:NL&<)44h\g?Yl]C>r!@phrfAm %Z9D_rY$&5b^2`9mlS_es8%iT^?ga62_K4;Y7Fjo6>ekfJf1!"nf).6u(:G]JHgp^8G:+/nZuj,WF6YY6Bpn573s\(F)3*9en]3m' %cY:E[7WS^X*gQ$RLirH?VT.b@k*^#VHXcqp3P;\>:8O]P+[00i&odYOeiEEs5MJ:RUp$b0LN<4Tqn[WSa[":WW!@gB=g2GOXJ9HY %qJ`R3FmFVO8<8#P^i64\3eu4@9f7?2ba"]i77ZITh/:Ed`m$sL&eOfZ2(mU(fcMt+/t1r7fNfpBc#Q#7*Ta$_DBZL%BU2)l+7jX& %G+k%V[[W'e;j`$]CpMmgJ'19em"?VGlhjTQ&0AAq]=j9GrOQ\9&6Z.p(N$o3ooP*??[;q!7Iq2q9*s0+uQ;0>%m)/]?afn6jL%9I[D]_174i"$lh_]'Zd`Cg292\8542e"7o(i'RlQ %Q-7`0fc_+6NJ0ZH,jEOrjt.i3s1L%S[?.Iic=QS_P'rdAffh[J,,<.pc&6;IqLuqo]O!hrP/=1=+C$es(=Q55QC9Fs8M]KrU`%ps*aRN %54'hSdsDn %K/mbhT0j,8UE5C`A(bp]StDO4n)3M-s3CY^*r/>*+"eLer_D+Yh[%tuKS&$#H7aBr=AT-+HAnMVp3b70S:_4299">LIX<-@&"lD= %7^]T2A+$6"p+;@#neRu"LZdL7,M'ofcJ"H;+ui;rO$26JYQZUC@Fq)VUAgl-pc)pQpYbenIeHKQq!lf8p_$)?flsIho%1ShhE!a' %EV]rel'L%ZNT;LTGNlF'ShJe`Ri=k0s%@^`/*Yf;H3>4VV&ilf6@IsQmg>-9d'MVh^j_WA7Zkqk7G&:8,.Le(Hu(n)/9\?Vq0i0( %Klr*NTt0(7Xc7oQBDsdGKjWK8>r3Lb[@jg2iW,F.BIeHM3X[%l;UB.Z8'o\#'RVU:i9bBE#TmPh#Q)UbgRn1D>Vqpq<7$o'#i>G> %K"g&eb3#41HKS'#Fg+eOo0<6&XXiG_*67.CRhe-9ZgsYN+*n*o/U(T:+L-R:#2$IA8(XV82^D/Vg'J61B:j"!htM@J4D[BL^?l\: %Gm(`#F6dql6pT39Ycp"5oSD>WeA'7SUTVH%c)/l`2a,A\pZfCg*-XQ_q!(R%M=*&r;-A+Il2CbWE;9'Vk.e\l[6'etqn,X1'u'*7 %iI1+f\K]_&RpEjG?dIN]D:JO-X8DYXFQ?2FNg:\R_*UAkl.ppF#(O+p3H5LV5aWA>fAH)T5N24TLF,3qenahf+S9nrVfm#rHpsU$ %lsOf_)X#uCasYS`#Tl-ASfI9S*nidK3>cSu\`gVVGuX1DGm`7bEX1@W*V[S@)Dr%nGB7pCXq6IHqTm`/Hj8(K]rYV29u9]5[#*ihi&lKI`n"TQbUu %YbDVDcZa1EoI\A;HOK@-6^71f;ET1mZ[6O,4#jQ:kURN/_4r)7#j2s#[0GG]J&`jiDq]c'T#S3;Dm"L.\I$+E6OFKNVA4>M^#Mnp %i6o&0B2D[aT5OmoMr;iaF-r*.F/4hQ"YVNSk\&FL;t0%Kkok#:Po]XQ?(=.nk5+ZYjL+ZVHjeZd(>%jIBQ+Jc/=[CZ[cqIBY`:qk %5ni"9mY^aO@g?5r+q?.bi:h,N)7hL4D%6`=?Mk[uCOAHbo\dl)/mbdF]5gSORKoGS%D&;&Ugr4LNr=ihpiI>M?u6Ne1la',\_A61 %irn^a(dC7.;eTs@pp4hp]B$>FjL<6WlA!t5ijtLG2E?4nc7a@qA#;,,Hg;=:E5*ULoP*]Y?,CAf@nX(ZQGXs/O)<9_cjh75_rV]m %nY\?1maDuke[@WtN]oh:N,A;NK6B7b95=aP%PCs5&H(iop5'%bbB)GifPU06Ho`W:ka(neIdJBXUR;J;OdWGgDk8T1eQYk@>SUHQZbXd:/Jbg5H"R`I,+tH0(]V_88DCf0$>PVe&&e#KG-0N-c=%ka&6p&=AH0 %HRE]KiQ9Rbg=$n\Tpckjg!O;?khlac-L"fBf9Q6`[V)[P'ut9!lCG**8^"`lmO`iSrB<9/4k=2'VX#9JiM2+cXc",C/b^g"Qfibm %IW'-TE=PpFHd;acn%r;Ug9tX2,=^$#Z+)J8Sa"n[(?&Q)`AG`*8>eV]/j$@JV`,'0aA^< %CI%Y$Hb#\Rr@N9b@;1KlfVOkA):o %R^L[E(LrueW'/WMDn8DP4nfqZ\8:ep(P35"O4p7/CqPMWD$k1MjCr#@LO8aK6i;$C?fV#J%QAm`nG11NGK[]s$$LXagWkV5Khnkt %AkPE=\??k/J,]'?ilJ4QiBngBrq]AH^O+gM:iJa5.nB(>FF/=_M_7%MgI^RY#58XXhklP8r$PN:YQ)f/*rkm,J,,OYr.cUE4o4a` %ISEN8(Jd]\Q9OrJI:i,%T8WeMGc'Q^o5/M+L %On[>+rmba9ln5s.EP.WPCGoKYG&utcXOn$")?A6<]nJrH\%_5E/I)f5B"nLrLq16,ms"W:h,a+f$;X$)3B81`B/?/[J&8X)SFm)X %>ojO+XJY[ID]bbK9s*qnR`H0823a]QmX_/[>Wb(i].`neXl_!U`^GXOFBm5EH,;c5kIWl7_#^79_ELF2R<5H?s?.u_s./! %T/jL`F18GB:V.o,aqaQrpF"a+ECdN$IG6R3oC9]dZ.ADc<4<;0F*kNVPZUqcS>cY2C/D=ae9*Yu,#aAC5>RpoTcdQ6m'RM$^W5aDQjS(bC73" %$3"CWV_-;jj4\-f_Oke.oo8oundApC(@>1QE=VlEI!WX.WR(NO$fL=J>@`ck4g9ch.s'gm'Ko_d;]!ma&m*kU_\YTS5lHo@KChDPjW6+\ka+b!F?pJ[T_-hj(CrMr"OEE.D5hLf,g,7_n>l6ghr9"8jE[32PXXR5WrkE@_!"4?i3@Gos;@uJ`,^Li6Ib$@/j %f_*2hMMdYcqXg5)d13f@kc_Qj:iXXIbmsU\>YF^ec5+g:kL't%$Yhmll`3WrFYa`,6'\VUiXS/ %mS/+U])Uihc>sPuhOj=N=uc_gTFYsffR#,bCFpDknD.tgd3t%jXRh^oCg4O#A&O/=)q/g)^*(o=Zls-HT\^.1G%&eLN44_>aXTN) %T+-.!'&L\mOcFKr+3T;d6?Z?j!Cu0%iTRr)7:*HfD+# %r1Q%$_&0G-^>C#VBqk]Q)#=,*Nk76X(=.5l2QII6?Ma$Ar0n@I;u%s@E,RIem6OC#rJR9l)K1Ub@7P^jh2\*oPrk&A;\Rqfq=&1` %B4EF1o>\g7ic[Jo[a03dN`aak+M>b9LHhM>+"lC^?`)gCg)d#<%Ui^+oBPj0 %k^jh1eb7[V3!Jd>r.R=[DRoV9]6MTGR-"',k!JS+"O"<=p3?BEZFtY_Y?k#Mh\2Wor:KgW4@jB-NcE]EESF*.>KX]7&t,?i_0^88%5'$VM(gj;GIa0sctEt[*$]2T?6hP`%$Hp93(]CC]&2m_CC*1!.r %f&QL?GhRqsYG&.PI.cYq@SS,2m7rZ<2H^X0Fg %L%I=aLhg[0]YM9f6RTT3'[^p-*`e?/>S$.H)^Ofo7*p]P]nI4Db9&r5^\t#*nZ0Y@`XcFl:VW10oj.Og)uSsPqDZ.TT/?[6CFjki %Y5#@5np,$4ZS0@;I:YV@*rYm$qXWCu\_m0/mSQKlS#P7NNo8^kfm6s7^M`=+Far>OQYdB[ht4tedeW4&i=F\ZD/1NoZfP,KT:t2d %J#._Q%h?`HG,U`n`pXi$nC!LNr:M)eY5Esmc[Q5%+9)8;J'LUR"]74))H6DfrPUJjc>*6G4nS)7"-&TQHJd,Zo$pPr<$,J+^8k%- %`duDPkM'IgqK;G[AGu)XV!]?GkB_&1r9=TPr_]se7:3/FcSo1doA90U$dQ.^2#ObX0.`j@2lB,]\fO<;45Kaf?Sk=;'8mol$.0Ui %N599;Sl;oc55U4ce'IKrs0/=1.t69M:DAX)D'Z!R+6SF5e0Ft%-*nXSbRm$4Wmo]BAGdQr.Qkp"!*'au-2K*H5 %o8e%-:'J=Mj9i2FDjeob_lL\1 %=LSl*eHgKTD[\^F1EXHr2HS7M7f_=+[4&KHCOrkPc?/_=)n8^-+qGa&goQo5\p"I`> %Lj92nYG8"R2=;=5f7FDL4!4&F>B1*H4TfOa`AViMK069]6?j*;3%>jaiZ[<4CCF'bE/sNWE/%W&K!>EIAa_j$lRM:?#<08!m%B$@ %`hrX9-[tbQ'muHqi)'fT*nF7\ETd\2Vf:'>WBkGgDubR[SF*V1[I_X/]>X[Ea?aTp*W=7!'!lSOj8L4c9/q@t^!4p1Bf'`+eNU.5 %k+Xf[="o*\,ME".D5RbKcMnXORM"moKm-87=O2I<\lR$3fUo`n]ru=0ZND;!p(PnCPQg6d7)?BnrJ.&L8&l*?pkYWdqT!-e7'JhF %JJ*n^f^SO`5A]YX/Z9C/iU_/pXN$trngaaSi5 %J)t1[)m*>6FmZV.pBlAuA?9Z8h=eCe0aH2T;`O7(qOEf>Lj!//[i$S3q&%bVMSgXZ&U<9WO5"!P>Ws"(fVrY_^[st0pM;2fCCJnB %G5;bs)u5?[2)T[h`W9n\EqOe6/S^]lbf+^Q%,SG4=T4oUV:6UuhJHpm9hq3IYVYYPV?JlX.+bPO_D?U=,3dn'DHD3'"U*XmDZ(#1"FSfK67Vj,94=$>EY_6et$pNA"L"]W!_?>\CDjtprE%U'8= %G98`NK^3;)G3^Q$QbfsRF:EYeYn?=@a1H`UkoLEHES8[Re!VBsK59r6DGpt6/`AK)-MEB%,eM<\n%A="]Ii8(n+D._Zt2WgCZbR$ %+-Hdk"MO$?a2`V300"=7AM1t3O-'a#ag`qb>g'R&1biH_oo;'2=7BB`YekV.=\$i&Sg*8"b1apimd%i9b"GUM@GS2?J:c%\C&JP% %o4-.&a)VClO!noH]^A %iV`s!^>+I`ki&o8Tiu#pCOti.LV(4ApAJh,SZp#c[\7(:PS-ZW`(-eECJH[\"T&TCONkIjZiL#:mql.Q(oK/l_(FrVIb_aT8bWR` %EPLYq@1=9__W]%E/%-&>2i6=l#[T4j8WXs_HR)D#[QPg#a*\"uUNoY,-g&X]n.kcCIL7!gZPJb&*;VP^):Ms*0tY[o5!BtC.DEjC %LVl/+kG:H\RpYgM]VS^N]!acA76EqL56U8"mT4!1H(iF6p,M:'caI3Y1%d;dl`u-"1jh<3&Gif:O.c)Inau3>bM)`?(qgf>;6nce %nPSe,RC;?0hT+#-"AMe/md+[$^.=!`^U;)i@c^"$AQ3MT74Br:'$t.CD(5]?Ecul7SiPc&m;['eG`c"m3H>@?FQnfpW=1#2\2RH$ %65(D(o]qLdV@$FFBmTir\h^Y(I,t$&p5rFQMdVJZqcr/!%oN`-kbtb='t,u>F_,sJg^%6`W=uUCQkJK.C2j'`XWBK(*>7^HKf/#NV]/R8edIPGThbk1D(;L_r%E.@2&Y.]h"gDlG6N1"o@PfJ %#Jn,qKA.!1f?&V;nM#3/rk7\7--_'Nm;*f4`f+!!DS*rpHh!6MLO03l->qG(10e6"/:sAf(dPZ09n#c/\rD0%2[SSaPul]k2/$$_ND#G0H^9j%(OrDU5, %?/%E,?p=\s()\7-U'b,jh%qT@U]35Y`#J9;iKdtH(At%tB!l@<[^+7:\tr%Rq%ik%R%#.9RjHepdo6#&5N2_2d1Cd4&(Wsl %LKDgJ7YtViaEhRURE6+4OAjN55i),\a4e-$f62TKC0ZCbqA"0"MVujfTa>BC[R3'j:?nA=)&M`dg#McG*.$c0'Rk+,JKV9.a*kB< %[aeKI#LH_rmSYh*.Y--"[3"gu[;6Mo=),G*rf^=HfM %DJ'='p1K!\OdED0%DK[k"OT#0`3"',P,[p\hqQ.jD@\`rDL0AOF*IgJ;)_k>gKp"a(Ln)l!^^F`g^I/,@P/Z]`j"kJY5ZC%I;\TZ %Ses"`_)!&N\rnSfZPKdq!0Yq7M*Ek-VM--_E,YLH@9_4M%dc->O7=?f673/jl@-\TESYeNnD26%C8e!4pS^7$?!-&k_d+$?5U!7! %]3dKa[N8ral3Y26S\!a+AEUt;[N(Y)i5\c@D7d8Og\*L)Z%@t7[iKm]6loN(A#ukN-C2JX]KK#U/3E'UJ"hUe=Tnh^GZ`GYHmb`at[YE`s;c;\"&j88`cI%!NV2_t]9S_A_K,gEA3;4'0k#5c1Y&(_Q.c5jk]V5f,nIAgo^EWHc&ULu?g@7&a"q`q!@97udf='oF %0S*i84o$;)aYmqMl,Js):"P1ko3,W;.sT#157P+;N\qS83->i-:kh.<>o@/X.su6AomE_^O*MC?In:-$K)Apj<8G"'_D?X?b((nF %1K%lM8.bLK+?Rk(iDq>LZ;eOgg=;5?_o.CEmqjEYY#^Ef]?/"]orU\Y`-p#CKHk7PSXDpoUoDuVnH?4J-(4AR]<)Vhsfo.@5rsH2ZSTsg.R)p3RWm0NIQ2]._[@OKA8_<9/dRK-@k+Gd4"^>T@32TJo %<*@mW;"'icp\C3/_%hI$c(+R`Hr]61Jp`*/A"+RK4_Z%Yo\5.o-UdV""^>EtJS_NrCWs^=M,3R@2eU'n9JkobX^Y\cF%i;5hgiC1 %BD3/-g%&q32;`H*WG[&:eo0rdPssm/!MTftqSb)07TY3c:eT7TCAh?hs3I=.J=Y=Ws7:_dB(PO9Zh[u+UU$Ak_Xqk-bo[KXfnq-o3Io*QQZ3g@''_W,)siXW*;+mAXJ`-Sh]cW%/8Dram^:V#i9c<)YJnP]H@0``p.c;Lq:"% %=.5'UHGi-+0r,ceqNE5mi[CO(EUHm:d)7Krd-Tls`:2nuL,TaUD:>$f>r;t*_m#VX8Ggg_i\\c!9cRpYcq8Vk9*VIs?I%@N% %Wafc]#W&1Jj5Se",9@.q=E'1OOhk>N]1IT9LfX*YNlofX:_lS?@bZeu^&-RP2V`YgqumF(+f_;Nt^N2Gk-AH36m %o4U@Yf,5UfGZ]?-[3p2T-=Jhp&hV=Ofm=3[D)XNnYthQq[Z:%Gb65l5*ZMuZHELH$Uf$nL:Ng\kdqeOOK0(l`2&Z^=83?>6GPSd& %IcW:kq),$\,k9O@[tg#\fjfHO0(Nu)>;5]Ng9O%(PC[5&E4IlCLcn0P$Q^6'4$U\"4tkbEn(4jPFXMC8dLa5sCr.k"*kShje<[jf %g?Y1qgW%U%ELCf+1(:8nYXgX):U %dll3aD*EPUE/p;(5>Nd\aPCSl`9J=Ck %i=JZ8Esp"-&U8"[c)GW-]7"r^cA\P*?Q!nE'OmVndoU;GH2#6*G&Y`ZHY=q4q6PKpj_-h(Tb*d";Q;)@2&L.6[SU9-bi#AcJ.!Fc %A.SLi#4WVPj)T"%gK2#YkPO>ne5WFOB6dj9HFBbEA6a1PYli2AjH2Imls!T;H4c_fqE&P@8!]$>6r3h>dBRgjU/W?FC1rX(BB"tp %YPuapF^Ub[QLa:NlIXK`E7oelYB@F^eoql4Z0N.rI2:UVpu6_TfR[1b*5NXns(Q%0BE*2gD,j@M'Fr%5_%Fk/-fuXsDu"iP:4WS0 %mIf`'pR8+dcY)8?IVD%u^==sRl$mJD[Z.Gcn+U/UP]Q4mCS7eJrH2_9HF8U41\7`5A03lmUZt>hDWEZWckg1-,BRKM>=Xip8&""a %s)I4^SWV]=gFBJNTA!uGfa_J)bl?0Fb1TCA7t/l)?]XN1_;P[gnWMV7GL,_Z0\n#PKTBd6Z!X,?NDFLTj!rp5:`V(F_I>.tkaT^6 %Adc`;B0!%!C?7:qRQEWg_h(Z'JZEAT#hZub$?BSGpZnl_6u(WDSkZ/+B*R@c^Wh)9#0HnZK9K]hcd/FV2']aTn,1mDJ\`0CUE(+9 %9jquM,C&l30>X0hhfESrLH@;$`&`(GM.i3\2TWbkb*i&j6sN/CJ&*[\^Z\it%!8GDdgpU+qDa %S#YN"BEq_B*SSm'E;9B[nU"iDH8%/`5ClAOZZQcs;M+(nYQKm%Q%l4h\>m!E2*ZNcfn+Vn\m%m/b@1d9d5]cL$1Qk:fJXXl[aS=f %cOYP4jqIG$[;cD5=a/RTYbH6'DJLsF4A)W5hs]7*BWOi%oUs8hZQ,r8QoTS7>%[c5`tVs1/6fXM?PW9=(OrRmqJHaM`jR,lfR:", %:YCU'T(E`a*44Ru/\\G2#F@MQ^p0^tio=H/aPWnJBq%T+M$;5IKo+ed&aVX!4i(jQFn^r0E(3:G3%D>Tmk^7Lf2FNX)+\P!!joLj %PMVWA9o0mP#J;tq3GRMoe<_V9?6M6[Xnip:FJ6At %M9j)mbagcHALkc:af\"WneE-mhhEXAh/Z*`#Trjtot`BXJCh@o$Jn;0gjZFIbc-L>M02T5SKn8d53#jW.nJi=k7:Jgrm#DD,tbK` %M%$T$AREV]f?)XIPOr?nHB:j-KeI(Z"+rD:0jDS9V;\XJI"XH"j%f)5WOTHCrSYnGP\JKG+hgsj8e:"P7RdO,!RT,5 %W52rdM2qLiEWihj+IKf!7V28<)DCLS>$?15$"$k:`j,a %=58CcoK+'945,Z1O+E@#<]E?t4*Crc$++Igr7JhW?D"^Ij4jD5gU?Xgobq9\A2p?0]`NZOAQs6VdFGL0k1VO.1!]"YWR7Ro)dC(" %Rs\=dWK=:j+5--G>;V&R'c15EMU$hXZU(-4<;6r@SrQP&em\@dgm]lN.4f]SNaVO1C^m=Z:jXRM"'_CuI/!%Kf5!uG[oemEc3K3^ %^,Q!_FO2VfA=<\0R*j2#c`QffSK>b[9<470K)PAChVFcRdTgPq,*SRm4LI;M15-+`ulheT@SoHUGO_#IKV5qC=JSKH]<`Pp<;mti'qI\F#/"OGo64bZlP+l:E=^_ %*D!@W\KP0MGNRm'XL@o#TpRQ:[bPf<5'$s1IQXuRLBlGopCKkpc@^dr?'[Z:fgWl!Ka?(M[$]fN2d$F.q[&XTo[+K`KEOs]&SZVNI][b6PQ+9hrm-H_rDaa\M`TFVjl1:=LE&LEc %%c@ZeI)W"da^3]lhM6n-fP5V8m5(!@e*GU>$8=>BC[9CZn4E^$&*Ki\A!493/?nI7Ra;MO=tY@Pj\_Z!!+ZciV7d_JKR(R@9HRRm %$ZF(tqto+>N+JT/Jb\TWdJQ)D%]$Q$NHB@P/sOQo2:n\N;2Rd^&PXb1or'1Y[8oe(#cQR*ol(F6b]99 %)O$HR>gD;h^YUD^i03c3\uktDO#c`W/PKR2,s@i4&oHCPe"=!(MK=$,%r.t"mSU%KrQ*[_F/sFDeeu\Z78)JSWAci/B0dj*eSen: %_4@.NMfd[$@rNg%_X#k9gkqJsas"BON?cMCGkL1[24af?:]#KgY+/GfqlHE6jLeEppY[b$=4pkoG'dYdSYe6sqR/M$lUiL>.Pn*# %5WY-uZ1,G=a$\m1^4UG4EtQ8F8gs"[+)H;[>;f-W>jc%)DMV)uYli]F4[uFc/8odr'[E7]pO-RaV($GlJ^2(]MG+6IR%%,qn@[TL %0g4PQV\/i*aH@:Fbjn3,?7t,^c("OW(2J+u1:M&]c!5_gWNo5OT*a3R<(-$3p.!IChcuO4VDjW*lRS=gknO7DVY,s(KeY.$UF&lJl%?jlF %b#F`Ee6iO:YdRT$CH9l!j1HTr[ru`28,5<8g6SejDXMAE37VJ!Iq8S2*@Rc@4#=_!=;HXagabIdK>,FGUonX*9a(t@ppMaj`/)6N %s&1qTn%mXBc_8iX3_QP3ch6_R!VKj\5sEju?u)rW.unbJluFj0Il%r?oQbY/^tR#i+-#1Te;8c9N?-W %b=Wjs4+KM1$V#Vp0XNX'N:V#6s,ruB/(8Chf0']%I8M!?YJ1!bcd;p[c17h'b\?05Y9ZQSllaom#h7]rk4__)k4L(fjdjL-'mEW` %qku0S$&paucSHBr]l#If`^#uJ>CM$'C\E^Ekc`?FcCQO`Pc_VZXZ'I2^.F9-[*&-9d8n;UNfn4q,R=_2de[>+YE2qO-a@QB6$"YH'[\GrD %+a.8ZpoZ05M2'lmT1*D0%*FcpD2oD,ik;u]XMecbBhf9&F*ss_9RM?]UNVp+oqD%DgsF=ir*s5jK_>#[nPET(+og3:b0sEkE*TTK %N^+h"4]XSe*@QcGZWZF)jasS#lEs(HPTj*[IHQ^@fMUSCgS4LD7`-8$q6s/>Yq@Vce*>#LZ3!/@aCb+&40aE"'&;J=C&GjbNQCW# %i8X(`+!nu<*rb7GW/oj$3jeQC(aVPI;&@@+J_WgD*Gr+CV"Z(i%4dVrl1hXhd4@ol:-Jk<&i)pg*(KE](m[1C]S8<[83R[(&%7+K %[u_YVbLMlj#tGB:X_-W0J-tITX.r3QX4hI%+BB!HfQsX*kH-br$D6L0!tC)+^@B#]4*>7cF_*KH6dnfS6d)7FF.EaBGuo`^2oaCX%"?](;O>YdG;*AfT#NqTNjjIk1YO@sM1Ym?:qKP7O@MAldpks[rImpmmCnBtBlYCr^4UL^lG %55eZ$FW?fDhfGX_H'?_B\^UJeIE0nWjOa4u^?:>DV:Buf\]ppe(9b%(DE5t"Y,s?"I]$1tMA;J:)pH/?YNm$+ %L*,Zrj6U?0q#*gKf`]6b2&IpD+r.iMoKY1-aE/Egab:UXZ7Po1A%5[XX6#YX[V_e,Z28YK&!IMD8!$/h)\_`WbV+&3P#6IB4cf;M %G`$"n1@VA*;bT:aT7kB0@jRTn1W<^UNOrI+^_3c;'2s(nj_euhVkgNMr02=2'885@u#0M?uK&g4NEs9:s&`l"J)GLGPLHrPDM%FK?IggErI\G_/2hLN?KYW#A^Si4$B``,Q#EG_*",VSL6@:,O`Fj^[I?D]sGWCl?9M0CX:3W>=^]!U4'c,!ZnlR %0!i!pSkda`EsU$gR*W:(,?eP2(X7"WB^5Dpolb%0f#]b*KpBd0Z^-FQ@iWo)%;;'+c'P0NM5mZ_"8-$fGm.A6-dq+&TR2OuV%)e!MIH:t=oYV5=*C],!@JCD$!*iETU&QGeM!$TZ-SUp2Y^ %VIf*qDM8gLmOVam.CGt,FkU\j@(';BE%ne76$3ZRbF92F$ZB;?ld.uER0E4k#M[)TeOWU4N$Fp@TATUl]iruBGL>#? %nJujsk>Ol$i`hL_bBc4h=r(VLoj^/b12k%/>i[[W/fSp&/E(d]hLsuNO*!j-gHd^CYt(9ia/.#2cH*8oUo;5:*dq]B5UJC4]!Q6] %>RN%M`e#q%i>KqqjS@*nq9eaPSY_0*U&3t+D6!2c_Co$o1OK<#9G4apke#]?eJ%ihd[do>[b9.m&bJ0D6 %32/Y&^UO.kJ)i5Bi'oj5*P[7_ %Epth5l,Ejq4K>7=hKsP<D;MoHH54^(SNNFB@puCE %-3J+5)NkHP66DFUkqOXFWt%Nqi=dJX6\/NW_2W6o,?b[Io,Z4Z@L%;`;.nD&n6gMO"&ZeoPqW(s!0%umOdW2W %m).o;,'j3)A=<*f*/mg^H%]\!f%/,C_FPc:]mgH<.M&gYa2j#'8CPA+1%&7L;YL!M0[7q1/JE0R%,'m6GkbZTH0]qlV#nuaPrbMp %G371%&^m`TAuQ`DFOdho,?(2B/W=al&XRC?:F=0\/>Ch*%gJqJgDGmWlrHYje>X;>! %D4nJi;D-",iB>rAlD&j7k0RJRU04Sg3p<8c=4B*Y;&7dRnX^t"oP9^.aq=E62rd>Z)BJdJb9V@QbE5FIIBlnab)Q/8YTdu0:N-l %-q&uN#[]dQmoTJ(4g.56EQRYVh`]F:D6Z#2)'s!k@-)-m'fcOJ4$[5`6%qj]aN^([miR6>3`L;NU.5=pU8:]e>+N6IjQsQE^nNfqfij"qV__23d3)oAQ!U' %_u1p+QhBY2.t'3LS-u!mq7/BE@AX3*`P:1^KJ0fAs(RjI.StV[G=Ol'REu/p1IHh&t^uXVB&M(i^R8Gas$;3]id;4L3CS5 %m2WV5r4:OFrfPf;hpi#$pMk.Kf3Urc)"D$dTF=*H[Q\?Wa!X0TPT(uC63)oQfO&;Yc9ergq/qPb"Hh2\l.]d%"kZd2P[9Q%CY9qHH[Z-QQ67V`P,K^o9(/:%&P(D"rU_g<=l>PPmNYcCLbbMG"keH#_=tBAPb>38HT"^#PuMOe4\K_MEh+hJg%.(ra^(R`Sui=SmN8#0)pF?M;stW`[K\Vos(o't %]Vn?EnPUC^AhJ+LagK^u,^IY7I]Q_E>DorcWWL[WAV>)Xn96`f[b[A&>?-2g:c3p@rU^TG>`[I6.r"9leR@sa`2jI$ZXuS^ar1>l %X]bDBp6"8)$Ed98YAbQ!``0]sb/]RZZ)XnV0[$QlN?"+*E/iJNFkU[FCsZ&(Wm`l<69"R$qhJ:UVmXD=#,U[)Z&i:pi=hJoF8^V@ %X.4>;fB]lHB"Fra/q\jW3)nsBZ]:@C(ipU.2DRquCBa=07rEh0ee0OZmDE84r+@"UI9GbKQL^YDpnS>qa:_`ROI@b8fb07E2CN)8 %hY,G1l4n)KILMN?)(U*;@RR9lAdduMR`#a3C@E0@BoQ:8D!P*H@q8YTRI=N8EE'fO`)1$tr)0uEM]eO6$%>gR^1ZEagt%cc3;"_s %`)-il&k=6qe0MKcN3n6uDcH=NlY8+sd%^a*a)*bpI3#CeiL-S^l)STmgI2OMfTn4X]AaKbP`h`gW)#P$;1dSW,8aUn[<9_s0:c1E %"HOrLq!Fu'\B"/2n'gZ,,h&+,5AK[lp+q=9A_Yrp7(HXWK-kc,Wn8h<#ZM.^,qY]6A!1`]Z7fBGd"=qpCJ/_-[[HGmcMe=I8L;N? %@@dMSl+>Bl4/g!H4FdjHnFqoTD9]_/kGW^Q[bnKZ;B8pV\nl`k8n#/,ah/LkFcT-K.r;al7?Hc^1InoheK^9J[XJ1[Xf_E>,=VQr %bn`E&7gX5/2RP-Z[Ni($,M37P#N`a^nc^m^+i[;oH#2SsHKgJX'_,@u&X9ie3BC:i@qP,-p8a^j[ZLaCF1"jUC:8;DJfjX".?NU` %cB8^Rjk>1NUj8S@/!/T\MhVcQQ&kNj_AR5f"]FCYQ"eS$Ie=i%J&UQ`^o">aLf['!l.JI%SPU8?_TKgiX3Wd4E/'*.0>EkCUgMWJVN]Oj':/lhcqnXD&ZC$C82&'On %:snc$dgA;ipamS>:UX849O$$^?/q;%WfkOJ`A!Aa0R3i^`[Hl0OY!2=b@bl"I0J`Vl-Kk.QKb+:EnidHDR02B0I/N][oLq!Yl;%A %nQj(t+8%,_A]Rc?bC]tA*KE3]7O\9/$Ee[aYNVu[UQn2=nZQ$@eN7q>GSU66]<>)QJq@<0Z=qTW=Y1PqL%3'h-VHp>nZQ#-(&ocB %@T8oJHL^!%)[.TgZeLCfh9/3&b"],"?Wj%S@pR'g?GTY>X+XRE0?\&i%gB;"d#%]in-aZhXLZ#CZ8"GAegRokqR>1Ecc!NRYI3b" %^>7)?M*@1^=-:bX$$RWaQUlrn[aL#@R*q7,hea<%GY\1SdKm1(cck11T_\okT#)e;ojGF!qIF4$*85L[00> %Y!"t@V/fTI29?rY/.u-=hW!RE'CPlRHZ,>mf9)ndY(1l7+.6]/23C(.pNoQJ,inI[)0>"@Ap'EI[E0O&PgI:?!l7j9el/u1[t3>e %o.td74`5dZ`!qk8J5Kl`9qCV/nF?:A5PU9Cc8k/i1tWIN5SBcb7''H.!'&TR&KI"osK6KdWSm,pe/>C'8,*G*'(u-8Wo'N1sePWKDtPE:C5t'8O+F&<"%2$*grC+-Is';B%t?l %9@*/iaYhnKO`NUh<[XBLEB_43Vd_35\=d$hXD^b:&cC!QYAorW9#$"<4Be[Jn`(4sdEjNQ"A+ck5dW,m(SPV+Tr&\ZTOs@/`%3cQ %+@Ui$:k2"B6*SKuC@1(i;67DYG=45oAm):>D%sCsCIQf`1b9=lUW@RD#6UEL;+0'uSj<1\8$'SuV(-sKSBAM?f_XOY\?!-7(p'\d"a4TWhEl^BE/@!rP"JC8KNK2Ko8 %LY,q8OhJWaH-8bLTh!3V;L]TQ=C:`gokd8[Q)>ps3J[0AP:H>I:Xe;tJf]EDf?#pZ\a(Nt3+Sn!rBjbOrBuXSl2m_Fcn(eXMJ=kV %C!LK^j,>Mq,'eU6b+V)%>RMb2Q:;hHpp>dBHidFQ<&P\6,_=gYn=(G %eQVHBi+S4Un4Lf;PkPbb %9J0KjKAJ1Z-LZaV')TtGc,kbt,t%f#E8VZs!32`G&3Ag=c8k!5g&_tWFC4LgL^sEpT'RbX9RBe=ih`ZW&-3p0$'-'\Xk1k9_o35: %&KLl*BnaV8#7]TmO&aE.lqXf`nkh_AjFu2R$&Y*&BWL]#G="hc-prp1`gJ=i+Go]c=d,@2jT,E[S-UqhG[SL`eQLj<0=C+2P[Adt^Kk%s_k`U %lL28(E\<)'9Qkg6U>Bsf&QJkEmrMeld1\+:$)s:UX9Y+JI&,hU\)JAqN7P$q6hb5r7qS:KEHarXV %lF<(5K%oJ!Up#IeUAV`]%_(0#Lp"*Gs.23;nU-$1F">%5SD#YVnm;?\<&f#h4Gs\=.4mi7fuZ^V!K1iKIrCTSU+59*j/r!=6,#bU)3b)qeFl\C>CL&292i8q$k&Kh<&Mg7cC8C0Sr?UB4o';,5YQET!tg#\AF!6ED+GQ*b,6b_:a\Y/>qHml'i2*:/A&Q8?JP^,qFQW_ %^L(Hn/:OuYn^[g^+hRbTLcsARaa02*3-Z8:a+Il2Up-'2&1LObUm5SIPOX&p/(\0oaGIkiV)GWiL+&V4l'N<[D=oPV@eYC;=mNo6 %WD=7"*a=0eqA!I\H**0jYiD9HSJnEa7T8oC#kr/$1%fAm>ES%K%ma"XrPP:o3)s8N_;erNIY\octL-.u5lFl79?teqmaJ[F[n7 %id2ViC]T.L(t[>J8'.-5qBtnehAT78qmM78f!IEn=YX^c)B[SEOd"S-6R'NZ.\i9]&V/0(D/r=QfV/.b3*.X/BrY(7l12[?BrXqP %&_fLN8=<^g8c8IVPf`TtRKBK@,H?>Rc!=%7Wo0M:$&SFnFJtK?74&_7Up2'W4lX8W\\tuh@Fjd]&Z_8R99*s\9F;FF4h4kt&9h'Xj>b&u8kSn7.PW(KUCfBJ %!Z`\W;pcS0Bf5rZ'RpW#%GlnCd*X%dXK>!=F]Ts#,O@$k/F%.SZZj[X2@>0TUN#4F)"1JTte(0>R %\qLWQI'hKk/TP:arA=Xk$-Ymo5L& %kUr+6T^8=N]ST@m$Ec$Zf8(3ieu4$a>obO_CS=E-?MAjj;g3ar/5"MPK)LD+e8-A0ndB^ajN`HmJ#j\8hCb(r#,J9,4f!eTBj,@H %c[qIsU:g4Wc%o,pSkHAMP_(!=H-1'*L+=\"Sj\]qqmOd:['JpF.n$NYN"-ad.SNEQE+Vp';S<\BrbRj'&0K$sOGcfX %c@FLn$.D]hr_eR7((F;Ed6bJW@F/[TVZEu_osRh_e78!iU3liplF5j5[Tj3dM/Xq+R$(CdXN8ES8XP1#r8j2+E\25&JkZ6\ZTe4nhNOj@?&98r:iFr\Wr1N;NZWh87G^FEY3(+J<=[Qc.edn %%McsmL"m9fJO9>-D'NLoW)kNdP^ol*"P["qC#?AP!!\:FQkML.f^'_MG2DQhRPr>dSH2DS,s`*%km5f8C>2W;mK(?NFshQW6RrG7 %-.Ns4@s)@*[*O*\F*.i7@aVU.OAUF@7G\t0b<,,/4[Z %M-K,`e9YklR\BDek]L_j3h!JA8)OPkcAG"bK*]Yo_DudV)*T?K^h/,a/4u-cLbSaHD8pj*Y!^LJ,+5;Q;QVHNX90c(?t^Ic"pr-: %#/W>_bp#qn95.L1rN"%9[g7jTC@7q$K.UdJr:,7+$ %.49QEkVUnK?DgMm#tm_l3.uB73%0knH!?()+B0OsTLCd9[S71&$j)N3d\&jkQ<$K^Xs)-F;Pl_]('bW+)lC7\EK,LhfsPs#^TjuJ %Yt?#&f:Y,QDR@:&\gm<2\2sV\N6#QKC.>bPA53;5GG4!aUNiBD<-#cpN%Cl*H@)'sDl[]7f3M`kR&-?6$fAqe6eTpPi$A&CiY!rG)Pm_d]:Rq#5^#?l8F %[?XT(rF9`i]*I?>]*E@t43$6n0('s=T%MhYrk>i8'(6jlg7Se1jn(bj.)k&H5XkpXI^P!%`E0:t<_XQN%sh]o?`W6B!Yi/@8*Lm6 %,-2J/kG;m0h:W^Kb3[8""EF+M.^_Lq-N*MF^j'aH@i0sT!H?38RVf@d6cMW?6dK"LJHG4fPODh+VT&mtjpOeT,`=J"#]/a/>#]Y) %6Eddn+<+6DC9FQa*6*asb.rD]T.IF.dQQ9Q@8]XaCdQp8Ar.ai3 %`%VT\X<;Zk$3:5!KG(*`;AW/VVe[6GV.@_A\4YglJIWUO8eQmh@\B5[TJ/_JmPM&F(&[3eg;7`Br"7^`"N`'O:"`nPg%I( %ADlCC!\qa;eK,BsR[&V%$tb_kbFYR:Aj*E@I6H+K6ji;&!TiLH;Y8V.ppEaWN[U7H[l$alM6f@M'7Es(@p^iMX5o_S..'fQ_DdSl %%_)i1rIm+k^*E@2Inqt&JKoD5_*uEn7?:HS$q+BBs=XJsXV0ZU6`#e>SKrdj$7%A?2c+:DW1eZmZ=fmu0b+-N/ %m&>J,?D$'ib#-@-dU^^j,dRN+=61#7E=bZFl(F.p10c4?)9F9\&/,KbgN?)W;`G'g]>A1E`,.na!uZ7_28cs7%GfnY`[,-DbhlG'EG2e7H9"KRlHSgEh'NhOOf#WcLsY[Wl#ELZFB%p %/ju-8b^W4Wq9Fml %jM@(3,m7ntQLoLVM#=aH=m*"N_!`ADA=Dd.l>N)E2R %^d;(X%!IFOfZ7G<*H=E&,lU^`dG7!ShZh!14"B.d[9I'8U*&$cjOXgEtFgN"0tF3[1PA,VqsrNJul@9N+WVB$>I"]9[:"dC%+.Rb;/OO(_]j %S9=t1&h'PC8Bt,*S]T)TUBg:$6"#Y>BYj>#W)#S=&$hLoP[7?NDi\p'WUBTA$;scg\Sl92pg*)M7ng3i0]msl%,mbWYZQ``%B&3+ %/I8Urq!:u6`V__sgnPK.V7SOfY7fRiHEpN_l$GkT3bMJ5&2=8Eh"PY7Y6D?=ZV`YjP_3a(.?ERW[#`]$#/+EdAK"Rhb$CGn*^r>8lK"9PEka>?jYkHb!EO[=#7/<:eobcO<_ur:;Mn"B*PSs,8b6n/W+cj %2d%FFkF%Hd948F8&WC/&st%aOBh1RC8P.CAkC_^5XuN#k'1p*u1X.b4U\#)YpF!!S1qSb\%0!FT=kB0n9(Z2m94+I4PU]9lN='sb>T$CN0I6S*eR,L5c78@bg?\F@Wt#)XHML$6rq,dkWSRogX+U2(8%#PlprCDGpr]X`Joa7n]?43gfpi%)PA[HZN5NG#fmRu]b`0E1Y10.pV&IdK(bil0*pnf:Z'2ZI9> %!UgD_]R+_sc'uoJla-1W=$_;Hi==o:I,nFa9db#\k3A"?GGfpThu(jp5Pb)85o$jeS_H*$YKq]FHi>+*lL&Qh`6Ec(d:[]Po@;[9 %h:Xm"J",P8DZ,o[b:U/AjYn90L32N8S_`]/lSk0"59":M#mYe"d/D9!rI41d]`I;Gl.O2)&,'Yer?H7%=#Y&8cd%#aHhtX((M=[O %#1jg_b/O%FT)-F1M4dc,JurV=&35WK0j2gXnK*d.Rt'hY'<$BR9u$n"B%g[(Z.I^!GEhoC,`O]kqAek8I]REZ3gN1O:Sj %+/qPUIs(Va\rQ4OlgN_YqsDYqVsOHtESubu+20gb.`/t[QZ(aN+MJ)CF'hq[f68ltIK&u!;]=!u.RO01#EoRFGP^Ipl\j6X04b5- %MaY8KhRqYA$%)IZDqO1cfj(P%q%.#S2B6,^\_56.=0Ks=^AJg1m=DG=+*iU%ke^\ioKn[lB/c/9\,Z$ZGG<;taIdsngt\R$XUc4] %LUk(siV`&'Dr,IU*hPjYh8Vsf0#3t"e(`dXj+j,ioBXZa[f41*50Jq\I9s\!IN17Ps#(=YNcK1/fp-;[,h\-mfLBNPK:K8'V;6;FE!N3)`-.A@JKgB %k([b(W9O:RBA[WVpV236X2"Ij]OT+_7/VZljsT<&hY`b[c$(Q'rsQ15:ZgcXh4IFqhPG'P^,PZUp>YMPX7NsJn'EHZG!6sQH$_@; %er9-M2Y-V*\)3e+8j4FBBNs'X'_gV)%H%dWZon9F2n,&kHi!CsKScTIoW[lHDbj_H]\,Es(-S(qhroWp0mqsar %^A[<3d<=\dq,?Eh)c-IKd1./`^sVkFUIcH\lgOlKqYPdAfBj*@Gh1^po^QmCQ=$3R.:8X*-\&WeTD6t4Zr5l_FRbF`bL\tK?[dgd %O,k;)kDk:V4aaR+J)2Ar\GO6TidA5u=#YWd=OaL;]\I*f/g"Jn]mIesFlE/bEWYn'q/:-m?o"XH5G%k]nU,6#?f.F2DWP#bp)edJ %Nr8(V*VlE.?[#KLhrj[ip&G')IQ6&'])8bVD^_'(r4%?<2t.cdQb2d@[.Qq]c\BZK:!5-sREc0'4qG4t(`c/n3%1,o&hl[JEPkB;4O_r^.FU:X4FY!&8jScX0s_DimFd(ZYGcmakZ*F58Jj %85VC\^:64P<0;R#G\Sp*r#H&H#OoK>f\!D^%(ssFCShM %_1d8U+Wjt1#8cs[0]O0YaSTi?3k1:GQQ817(\5b-=0LIsN[)"$XC0694;Mi(e+r+ec&\@>C:1;;`j;07Ck#_`]$"=0O^7k?r_?=N %g3.Uh=+9c2[JZ"kXS5TPpgA2j5bm(Q0Y6Ybd7p3kcbI.V5JR318hB.t=7,S1A7c,";h0FA%fBuFna7N=>D*:,Qg]?S00F0OC=lo#*\c,":=he@Ek]?R/j1nI)@`PDiQiJgZp %*$oZ!bK[a?URl!Cn.W77*GT9S)cLu:2)I4`aI_#1fXsnqT%D>6OpDtq+1"*`U9SS1nD6C!#IM^mgUXN#@*d`U6iF!4HTOGOIcoRZ %YW[Io(FdamjlnnWSbdHccH"u%htj]$C//V%J-Yr2LRM/&X6.o5hnT!\gX?[a?hAS&d3i7+i3>fR)](q)AE874/$q%@k0%tQdlsl# %*tN>32P8&dRnr+C4m)hBcHU65]m>*U7p"^Dr8gt,H80>bT^2VJT';5CBp(Okfk[IYcU$ %S!e(F0g13*jHJ>C-9khLg`i7b>CZPg`Q`&fh>+Z-&%a9aq8\hp5"26d#H4BqGbhBm;<(Lj2=eS^Z+$Ispf*1jRnr*Qe9D,]n%ks- %^X)>aW3MDRr*\#6(cD$;W:>_DAp75lIJs,BXI6c54[$D=^&5dm`TD0po&C0<)1Q@=$^t>8\b]fAK"l5$'VYQKa,`_RhRF3C2lEk* %IsZPA+)fH.cScT:B>=<,'>2'TlL*["llEOF?5]TjJ%<)E@L#t`o?h2qp>Nm455%[Y1McAtU@[M'q1'C0^:XeKYM.A>>k?M5c.1t* %iPlB^SW+dYmVXq4X)B%e.YfcY>B#`1.RUUt+E=>coX!".e1US_&([Ftd3hi(k^uusrpo4FRl?\!]0.K.iYKE*SuWH!ZKB<'0Zf*_ %ZB*noqL"3/V*,>3HSY,$rlN-?D/mW,nRM=;o&6,RFo5V'?>Q]C5".,Y5Mk0VGP^mic0!c=k)Vmjfl&5*O%\,X"b4B\`CVDhlO25_+fcjGi&DQgQdOT3?.[o0/75spFZeKjSO3RN@#_q"GF73$[TB$LTPAXF'-''Vtk"n9V%j.W8 %36XQL9H20IO!>Y,PJ$F4*tEAcAAVb5T?1S_Q5mbM%cK,=neccVi@t70$&@2ckO8:@r+*ZQ2P8*$PJ&&N36W-cCZ"U%P6m#tHmXnC %_V;P=R(`4n4J$5X/[!m;bi=9Jn1fO%C_6nsfS'jE$_K7^d>&[V"9%a;:pP)!qLEp!Z>kejm!6jqiQ9VdggWa.RZ7'co"f*"roNjG %s7O_a2R]k37&55DOZ)?$f]h;kj+j,io.>WkocHA;;.&aF-.)`GWH@2kFOo/O2haD9-!/]9_*`moJ'A[ptu\6,M7nb %2h4D?&.V^P+'[:`6db>T/0A6HmR;SdrRMfd.RQGBCnaF&qtfQB)td6LoY,emA^`(mQ.tpa7G9jNdWSOnPK]l+*gV24I!n=-OI,?aoCaU*`!^3sK#92=6UF,,3>+!(RP@p:"72c$A4 %#ht-$p-%3-^V)\CrU%Sk5+"n7AY8Ed^Y+!q++lj8C^uEBF8r`:/=%g$H+6aWDm%Fcr.ql)P<3?rjiAHj)X$I2LNE0>kA1Nr\&Wp@ %^3ljj'399)V>N!UVq8+ZD1Ek95NdHO:p]VBg;:dra']@=WI5HeoO&4*`9e]f3VUMSj[%MOnHp=H27FI="9%c1%fl9%i1HSLplg&F %i(mS$kQ(U(cR^.Zr(3[7?@Vp64L&&>Sp*>%NstsNDX65oa.V^Y:Gp#G*CB+*Z[@-Dp3.UrL]9Vko:q74he#4sLW/G57DBfn+pWPb %T^Non]n=%Cd.__8pGNe[T;''o<0O=@c=_BL)W/P54",I]Kl?j^*u)GA_KSiO%LV*';Y[7SpXd$l?bH=1o[C8*D`mjMe!Ckh2LdC- %r36AUm5KrPH#\,@3H35QjClIlag@h-!q\PZc_[P,i(m_YFS3o'-']bNkC4S%F*VhLFo'9omc]T*s8M`PZT%Q,h9iFls81h4G9!L-`TbGa4$R:8epgB-j?uQ[m^Ps, %&+uR8,VWA.PU88j+9jM7YoOAp<:^9,4ProuF1`b3,B:f$_I9l3tO2g80Z1e@F %I`UQS&*$WG+WffO5?D;ca2:l#U:.-::1ZIITao41q_nkm\;?^;@p^G/l8$=%0sM^R@@2^-$tIlGkIP7OdbcOp6S?f16Dr5_IhhBo %X?T@73f%p-UE>QBW.QN=qc)b(AF>e?q)J4*;6Te?N-XDWX[f-#,5NJcU_./#V$2()V]k=+89#Q(=H9;AVi^3WNBT%933F3kGm$.W %&WE."8cC7QlWL4m8k.`*(1K8+%0MSt3j(OYXFi5SlG/J$KCdeRL<7VZ,s@R1f-TEjq,ksMO?LZnlLl`gFd)#kf!FXe%7BM>6lnUn %q\]al`RfV0!/>_\-JmM2_,toOgJ5f,-lZ4MP%=q4X`6Kdob`t*RWY\oJi"JE4Afep:\B%[koZt=2R-VE50^(.9MUFE6+4k@mF-(D_Q=D+E:`ib@ %:5n3f[?1r(]m#L^;%3+ML3e7/hUZH_ooB9RePW/(%@TSRlW@[2L.i9DEK-6Ie.ZpL*23kS0#Sg/,/c?VEq8SIrB/Ej$V4(:d2CV# %hH[fXHMu[a&*HGa2_WK=IeW!X0E-'7q>KR.5QALafDP84rOfjrhZ*9lf"pL[NM1B[OM_#XqVdhn(LQ,^KilB$7cElops9l>d-uo# %2ja24Pm*Cd@W!7P,#qr:`7416f8\dr>Zi('R3LfWcpai3Ng47uan0`-SQr=+X=N@W#O;tCd0Y<%f6_Oc"Nk_4:AD]UH^5!\XL]'/ %%XL'#4hHh9saO]i.Cd6bSMeq6U0F5=ag<@snT-<:jQ.no.Pl<8T3@48M"?3,/]0Z"(J7om.P2Xo+:TT^iTh(Cb+9i_Xhl?B\>+%C8qn %6PJucY[,:F,4/Hn$_Lq5mB.JNaf$_T8go!;JhQiea=Bas?H!dXIt%mDh-q!\=Prh'Y'upV]jN/Pdn0#,/55.Mot9:LX:LS_5r!GD %pJbd*mm`ss.?A\$VoLIuEuCbIHB/7jXS#B39qs)In.hu$PaET:%^l=_BCrK*J_p\VelOBD6P-pE-919h<+fFmZMH0]_lF#mSeZ\r %gqX/.aFi:m067k_2qFlpB'OHBhs7hsF<+9?!S"q\b_><@O_CJ1RRe]]oRcq4)c55'PiZ<)(DO/FI6K!(jbYrW0<;[-"jW_<5L9=1 %]q58QUr:#3@p/TgZeWJgQEZobVTL\Ee'93\[`_5!kiNVG0BlZ#A!P_j9`'VCCifl7"8jk/2RG %pEn>s`2A,FDL6]q4W$MBns[qb$HM92`LW$8MsJ-JUGWmHCtHe8YMKM2]!lT?*6cOdJC83Vf,9`KWir$g\8F4NLkRfP2E\II_H2.1 %lJhR_O%d6S.BtGk7?j(\R#0qU`Mp^[h2V.g]=N'dl;Y'1NfKau>SY8+d]5E'KdDbaMH(lc2tSlhF&=Sm]fP'c,G)k/JqKAJ]>B_1 %@54K9;6>XVj[.Y\SE-]_\(T0rjr;-t1LGFYD2T %&gisFgdsonefut'g90e-=Lk-J'U9,R?W;mej/Q/jgoN\PZC@XsWD$ARh_;:co\T"0jchAGs/gc=($bXIW@2)V&k%ZSS>I`^=c)3> %P-/h,I2;GU$t[kB[44[HVN]KOEXWOOd7jB@Ua5dFh*_iW$8K$^5%b[%H"nhLp$sc-?'W&,iPJMoSi5+,6(GW+@$V0q.K[`Rc8$mfU/P%qC61H' %9RK.Wcf!K_fC.sO]:sli^!LoD-TU)WnJRMCBq2E)HCQ4pgS$f*")CN9jA)(ELiOh1h5U.BneiY'r?Z6D(j&^qW0?fd>;N3h4e,)g %S#_V0HXOKjBU_5u"M'a@QB*brTGj<*k:0lG,tipQ.chC"ZBVB-W*E'^G:6qMo(C;tqju&W1R_R?Q%P7QK5[@Z^'[*4'p5'N,GGC" %,%&ZiWI,dSB\6c'RtYlQ9<_$Uot4(B:TK@P:X#2*dA)IDGZOI:EhdfJb-g6E.WFLg:qqa2:IY)Yr+i%'4])Ma/4i6a84&ho9]4]@ %@]PQVO0"I?99P]rnYY=jQD?"FK6&F%.]e+TH]T[Ed1dd-):c0Y@t"AKc*-3.KI7N1l9Pt3!80AjXMRpO>*SL(^f5`\ %C_*]P?'Y816sIM86l8&M\ai\J<\)32qo:XWq3hK>8?,A^psV%`5g5@tfPrGG(>/g"MA>HlUK:ZOHE/0HX'eU?5Bn#P7Eqh'+)G)3 %P>,ME!EPlME8?0%<2-BDW4$#DR:^pqK4c3f4NZ%p92LJ?g*%fJ(^SNIjcW;k$/C+P(m,ns\um?9'^okCPNr.nfnrdrSJSmj0sP// %:g`fFlg;XMi6@?!aW_KI=]t29XJE;^Ni^"."Eb5&P#)([L39o<%UKQ$oP+eFiu)A;HK=0:iHK=@K;BeC&%0&,Df0;d>9mF!IX$b/>b4!65&$>^pAOM5?&KIuM='aZCR2,R7:""G9H. %FE0r!Hef\t+?O:1DNh$m?a5Nq78[c0rIe9M`LZk^'\PsZed*1q?3M7)>$*-(D'bb^eTeaR]4Y\\ZU(^OkrE1m\I54k#0.?%\g_DQ]mCF,3%2iZsTsV(dFu]/p)ce@\["eA.P)pFnQgs"@KTqb8lHHlS"!/4>!5B'X&XUhCb;`*`tCX:]p;C]?5YV-+D,]fFMff<0!Y?Q %D4ZjV,]q],lAZY_Mc?Z2GnQb7CJk+%r4Z0D*/<t7Z*!mq+9]4'6R"6F.\uu\n[R#>cf8Ud(:WP5)M(O2&:.1P+Cuf_":Ve_H7$(99o5\g&]5U %YU!:W018!KW%,/oC,Dp'Wlr'S0kcK]Nbr'PM-c)6aMSVp7se#*pBj)od7#KlKj6qo:5O=T'JeIYerj;-;;FlFq@j;FBe4!T-%V)J %>M1,r9us%48#?sCmtq$M[Ca"`WWc7IL7D%#1*WA&".FfII\\7Jc$*dNMe#H+@"J"%W-UKNeT[0EM"!tginf$#X%S1cQKdUe,m3n, %4rbb\aXc9@/d]elFNbbsY9[c-(!l*9N> %QiD]70>6Tq`!:UHa&$o2H;V!57ri8E"m(i:l9-`f?T[.Rqq'T^353&9\R`$Cr6sodh>-I2Dm$(tmI/n:]TdZbcb9n6G%?U3n\`W= %h-W#&n[#FtHBURcIs^_^mZpAp)Y+.gWYXG>JVe:Q"d9a1PTUgkPLP+M5n%J7"$8rLj>;Zq %KTm$bl_*)pH^C`^4H<5=kkCn&Z(1kQYib?8:o@`$0o)O,&ntdY_6L2.mIirn)1%gec/^T[;^l]mG)m6?Y!1@a8OMJc$DaU,f?m?t %PZ':,`==@eIo_R^A6):CX#M5;cY\;4sJErVPR;)Jfg&!P)l %gKYb'b,kc)ctWo^(MQbdFK%m-52=,a %QVfB@4OP-/RCp11)SI%92iC3/8HKJWF>: %o?8_`;r!uF7>n=a(pY`eScT[+-H8ITDj@nJ*('ToBO\8&Wn!6W,-_G6`[B)]>Ij]F?bbQDld,3Q&J<7p %&il[HTF^SAU!P)0[SJr-CsIp<7t:6?r/E6c"ZjDPppna!3R(7$COnG[/06g]`?AH(94e(E5?LK=P:k:Z00V0-(&/#p:epR/W9d(! %<4PF1JIPlr5E*`'U)8f&S.gK?3CHdfTTQADUa6_8&EFnR:Z[2^>S-'b>EINK;i(bj,Io3,l(Nne`''2\.a!MthAUZXpmp@A@S;\# %3V=qe=A&9Hl%72.$bu6pb.T*H2lMlO`8i8sL;Ui*'UoXp8C6hkC*V`5p?Eth$8G))qaAb.dd+_!!d^fG>pa.^0h'kP2[59*Jk!^7 %qZ(*fO?-O#\q$g*X%?H3$*,H%Dq(gTIcSW=dkl5`W>6FV#dbX]2'sie:QWTLY0H,T6uUgG9Pt]`R=kTsC,\JQG7nl9nRVQJld7nq %4cjbWJm`ZgIITZX;f*`eX^@Wi0@%kpB%K\^l]p0!_X)MQG.fFg?^708b0JULf1Y[i'r>Buo-/2l`Fotp_h-J85K(uNs$^kq$RHPVTYPkjB)[0LA=Yd!2$nms:3Z]Z,>tP-@O3sK?;eABO %Fl7=!UV+1WUIot2a!*hPOOCI!!Z`25?Dt5#2epd6"*,=aVgODdF^Ek\>1_Gi*Egl*-]YhiOFpWF5EKUOL$:p5\uQHGOaImA4CZ[D %)krcSaH06Ji%q5:em4&m#-p:RF7b0td-=A?9KXpM3Q%$U5p?,cOs;1=F:ubli"f/PHfYE+cNQ2OK;o9BL?*XZ_n%/@k:-_d^b[1c %kucT)pGd)>>@E(N*!6?:.ei0k[1EgDZ._LO&e,8I$X?p(.;@M5XX44WDj,K#@I&i:5Zm,l0d %3$q"aO?qlFSnkEU>`9na_)6* %?%[g98c2'*Q@ZC]F:`i9&d2(uaEd$S>V8*+OK_$A>E0E;IA5j7G"^"l8XFasMCmU"!s8=T3)*/)I.;nMUnTmN^O=IfUH\1Thl;cP %g[(Rt'L-!=L6/'-&7^e3fKWhWA2.PTMeKui@(kjcTY^uBChJ[oE7-n-.LXVk(0KbYr2Z&."]CD$93Q'F=l=hLQahTp:Fm %JM^PH%68)+S1`Rup&5No2@j!AUe:C>_-&*#:3kY,XeJEEdIN)!'X\]F[G[RfN@,(dAbZn.fJ6%S;]1W5Pj7B@&f-=@G3:>:SFh8n %8YSrjXA`V2l%Pa/4!.-gV"[mu%$#Bde.f_gJ*E:^a\fJ3W-LaH(b]WZ@P=]O/liU/3[e1$`=N6I=V8GkWn2(.sX`*)+39U.7-XiYZ)8!U0"*US0ip?A9'gV&ni6h[8sA8@"$M2;ofPk(X2+T-hh`YV(tk*>#csM*P!aU#`5C.2`m_$3ZR>5\?;PK[A/3TH'?JqN)WR&p,B39jahR %Ga&In@b2nKkbX.gkeSEAh'Ep9JfQ*loVJ:u&\K/rg/?+e6O+fc-/9r[Ae6MDI&jo-Y0i9f\M^0F;Ff9,U&7U&A5`GF"8R$`pe-Y/sgf:PpPQlVKLbI0WOrm,D_dGKM6AUGS-$[(+^4(&QY,0I*U-(k:ocb_LQd"HrM&q\%!G*(Hk5-l%&AWTOs&i;W5$>+t-p< %R(s1%jL$9aO4`k5UQX4RuHjN'(:)=ciX/D=XWQN^%=2M$++ %gn[?[PHf*a4CR*"?[dF:nfF+TQ1OdmhR-cGL/c2Ni!h6;8;_U]%7s*n:9!8f/56Ci)XoSL!WFQ@:6sZo@WZ"8A>,@Rh:enJ&idug %katHgnP>#.(dZ3#1b^+K&;["L&[;K6js[Cu6p4DirV4cAY1if5'HRA11lf_-!sP2&YG_DN]2ik15k.P[Man*%jb=7S0jj):HWV7; %$]=ei`_nVn,E*,N0Ej=2%M8_D1tGRs%H8o16K_@hTFq2$3'ZU(e&dG[:Y%_V1f0PAQOl$lVE'hXoMm"7GHtnZ-k73MRH0XSuC+r_&pVo>Yp9.rT)mc<=I,=%aDFO %@8mlp=d1uXrpo:)??a[RnCE-n[h3W>j&(YNo[)$MnC3PG[U-r?+_sIr>\'(]+kJ_Bd5lt`,oJ#+!I5kWp.;C2WG1Vk %'"qu"7.a3AY2XU=.WYn>qNt6NRu0B\*7G/]C[./KH45[mg%kY7aXBms`/J8!ubH\B,eBnh4L.tjW93F,*=l4:K84];@L8%]O#^`Z63BS2%'hBLL*)';R %/2`*1c#!9qm'oG/#mKWJ@i`U0sD %BnXdXo#D-GH]0"T#tsR;G*(dWU%N3+jn)MG&aK(g28kmK#+,Y^4\Jqb=\YGGH]43oR7MV4Cp>fSK?P$?'fbn,,`S^[elnau5FM[dqjB\&=Id:&7a30fqpa\kW %^T%8!X8)5N3pJ1(4St'ccJ9Rnf`F3[-suQGclSJR4@X]^\lqD7j %l8'cZQL5ik1J:[mjdIL6.`KV:d&VtKVO'4h`Y!=%:J)e2o(\bCf@GN&HUic&QOUHm[/EUFJ %i`q]?e9a@^o0O6diu-@.dl-8T4/hFpp=lC85tt-98a2O]5L#QUGZ8]3_2c]Hh,\R5XP''>6HNA($=$uT:IZsS673K$@]f%%YfQWF %$f3kMe\"m+#4+O/b[V>YU:997/r1O*a#p*U.H1AM%'nJiVGo4$DeB5s+HRFDc<<4\]*XS)X@@!cgD!82HYCtXPg?h[7d,.L#R*Z2kHa4sEEhV9(o%*3dEU>b6);W1"?;0PCFTF-$-mn85s67tK^Ir,- %;B]1:f/qXm326r.j5_F8Nf%UuR/D40fQ(=g">X]t$QY90p0c+c_fEluoOoVOY#`=D*3L!/dUMoD^=WTW'F;5C^?[p$^uZ3qP[s<; %ImcF#6lWHb(Hde,HO&USYjq"40aip`C[p53!m`(mM:?Rejnga5B)`l"DnkLCj-%+%\I=i@%Nl?ILeoj'4kp/V:U9Xc&Aa/rTai`? %9X[kGX'L!A-k\d@V<3L@6g'Wlg)h^=X?*a%:tpSN.Dm0tMb2t."u@>j/bPn-Z4uJXRaH_92&V(>CE%m:Le+qS9+k`#O;>\7Qn3pu %TZCNXK8g\0(poA?'aCA"QJ=TL4Bh)>/j]LWHOb^b8CLGKQb'pEQk6Y6.?94q-e[CTr/q0^eV,rIKTeKRekV5m+,4rZ8#P&X)m]-# %\=gMZIs*N('tI@3BPuEui:M,n""p/m@Zu\_S1p3bCRQ,pnJ]*=PMD^/(-7;NU#LdUOJ!*;ju?"7+iD1HaX@1t;sYslEn/ksCfUXr %A(n+H&t+UoVIsh%U+7$9S`ZkEeja,dB#lj:5B2`6boqK#a[O&.n'\f2(!bqQ0+74[mu&!,UL'FW,?DRn5rj(?,tBR%c\HU3lf=m %8S*<.22q[,,fkME!'&J.U(pmilI9Z55MZ4="J<-jpZ^&IlP*o3nWO-0u6);:D4(6h9%L-#'/A*2"YdPb>2t/NLps]-@#AGL7a(UI(mjC#dr^5_bZ)c?4pS%i %&\m">pk^!WmV%\%bD`rB7E]/F[,S3!BH<&,la_U=.jML.SPipm'"^V#9.%-bcT#q.LXIN]s5''X>J/A+mh$R9Ys91i&HXYaY)XB` %n[I/OgZ3IH>ngcn3GPq%/hnE"[uf35oO)c&g(`I0l!BbVpZelXL&h=BoKm-E1(M!8.b9+kRVig+^p?lFKI[LfUCO0#opbee:$c4f-U)27rmGu[%WLpO2(`C@2g1DZWXVQS7A#mLF;AZF4i1hA4%<#UD3#g),lGfo'([FITM_BP\[8)rJ=l0Gf'Zf*kof9NU`[*-'BH/!KF&UqmlA[smj=H,2\';h63eBVmcZ9hlZbN=Q+ %HU!da!=[;1p*gls&r=!&BtsXIFl*a_7tKZGPf>Xm2>VWOg\ZiF?,a?tp$V6TkB$T`WhNjp*UR7.f#0`%6!Lt!rW@Gp?FaRb2`$]SAgl)&62f=?4SNKiuHH@e7 %G[09j?4)E@<18GB1_!!I6:`P,Ql.aPM'Z3Do5R/6g_dYs3RmqX99ROb+IZ8"k$B<4EFb=`9*6ru37&.=*#2_A.D$qB\Lmo@,n/8u %`Xu_0RQ$rHC1;]49TQ7#\D8X@'KW4,+`3\POpa<[s.--aECAYnBDW3Zcn48R+(h8TLqMr!+AU)/apHRd?i3#G4&m/rWg-ZrVWs(N %!_53[m@oWPF]j<2[9nu&/#5*t#\n/j3^C\?6jj<3F-O#$i3!I"bmGE*/\rm)XcLS&"9V542dnnnCk0FO9U>'[#/H2a@1M27iqe8. %aOkZAbHH#3P9%#reD-'@3W2:Zib$j\7uZ$,K/4fi"FLBUC1N=VSa!.li_3/$.Nnqa7%BqIC*geH"^k*^G2JQ9_+T0C19PR)aI!2P %*LdSfd'Y]/JO_=QS)9^4O$ah;8&&!B+*1V?MB.LZ=55#E@1&e#&01G4pG.R6bREk+HRPsC'U/W=W:s3QVXg$VfV9fuKa@2@Zu2a(:U"06/s[-5jFHk&'Q'^1j+EW`lEFN^SeGI0fK\]jlo %Fc,h!*%,f/N%UTD5IB$X$qU6R,$?807jOT,fo$;CE:.J?-IDgdgN##gF,;hrR^t#7/E1PdAj"9+cC3@?SEIt>ns3P+r?@8S985<* %H[uI%\I*_69b5Y2$:N*/4R/HlSA*DV%/aA6g!mdVFF=s[i*)B^,cql`!laSSW*X"Y[,7@@!U2HD"8/=OJ6$r+7kROb9+fG*BiPd& %MMd5++`K0(_),^O`a!-(7PM^*+$2am"\C]O]WJY1Y$4,q&W']Rq'J&RMZ.>USLc?%pY8Dpk9sLj/>FL7Hcmmn$JCl.rOMT?;?Lh!!>_MVmFMU^, %3kRP'_QHC9H<36RAQja>H/Q@lgBYaKJpWUP8.E!#EtKNWFPC(!!">R0PFXD67^GA1/foH`-eO=Ol<+6d^q!qjeAuNuA_':8>8Z"E %,kpL[9C8Q&Ztgtgmu*QV)(fmKTnCKcEI1nD$^LBPcpiBA#U]^d+VlX$JI%'/;5=A@22]+%%(+WF3cVh8<%'2]Pi(089:*%VU4R\, %'g:(Ue.V>nq3r-U!J=Af\%`P3,RBE:7_^X%ATLa,1Rd8MnB6`6X#0XEa:fa"Xk!p&)B!RAo$(2mRaf?K*$\7(9+X!2JH^Jl*@4Gl %a]!Q`&kWO.gYNdM.7hs7JGBoVOmBA>u.D`#Qonb@bU,HJ&LLb-+MUK>F#"YqCh'c822)h0INk^`9- %bY7F,q?8fN#i+R99btR>Wcd`GjR?(WQ@qfl9N#D2",EX])B;q8%d9mS$fs:7EEOO'3cd\W"s15ocnFI.[4jFt!C_J!_L&V;nD,u, %AI>BBLS>Y3&0jmX;BqfgEXN:p9U=F3_^$5RnELh(AYH5pUY,d;6sG&ea);B8cL.$MPAj!)bmYEoP)ankB6

    aQ2)@'#]ab$21NND2#-)0et8D3@!BdQM406Zi:8F#8fk>la!e-W&D8$Y %MG(AVMNN7a/@LJ1LPV&qVO%LFZcuhkr.n"r-']ICR,pRR6+p,!l4Yh=o/T^E;*N\34mF_SJP\m*L==8oP0?baXoQ,Dk#DiLsXS)::I=:`5-=C3X6^ChSTjPm`^Rhthn %!Ol4r@WFK)a#[:UQ?"m]er0JuIN4@6;/g0d7WEf=ekRalYQ)"o2@MJ@N"VXg_\au`aO9P/>@TRMf7j>@7b]Jsa`H0t0\VQtPZ$=fAG(Op_ls;m'4^ %.@'Qo*-8H'8j7C_2V?(d;oAut7SX.DUder?C-^ur[4d\TN+fuQG*6HN[YAX06/@l`lD>61_gcY:$RtT7A*-N'+I_34@C'@N-Ukhak>MLd,fji"TK5]TtPUog1E==fE@uEQKc\R_h %E$kdhO&iNFq_^Rgl<+jPTJ7+c6d^h$XSm+U"VIE?PS=E;E(d%.+E\M*h9suL*$`n<(gsTNYa`e]d %m!\?[CW&P7XdV'W!i[?f1X$4kq2Vj#=TRJ.ENF\\XFbWilkKm`+`_=gTVe1ZnM2gBGTS8>mJu4GAdD#t;@es2%`L91O6ap8?K/JubJ*4+1j1jCmlJeP^+9%V<#TjHjQ+<#6uU5=M2k6s5sc?a`.Q/00I/sj-mq"3Cf3L %9]AK`PC@YEXh(u\A0s\CnJX=0&rQ@_7U;7sd?^K2kV;)e6(C\)e,7FW&8FX%B'_a>_j!W-u@RNCFEqnsM^;h#G!r]p]0m-Ri`ZN;1j!ju)=tef"X@N4\k5a9_M]1S&g@h??nQsdT[Yb^o4&I#"qN^, %=W3.^N*-X+Rmnm;SINf/"ZmFIBGPt:KdEf9f2f"FE'=8FB_4]B%=oF@P:Ip&o!PU+(PA8CZ=Sl %Cha=Nb`]4JJ7G@oH4Y'Oc+a^3)BstQF$o#A*"T46[slU`V2gP[p;V5FfFjRAkle.kJe(O@g#2&(#[?_7L7(qeB\`k7H6q=ec5uTh %g\hOhrLM64a?//D-3iW3s,fbt6b.fJ/WlSWH@HG!I1(R:Zn\ %'FORE.&?'9#96Y+@OEF!g$G9689%t%UQJ.ZbOJ-bhX,ncqD2CKq2VDLYV3-;P(M6PJ4qFum".q]P1EClU_)+#^aDPe4!9b[(HZ&i %_MU*=.0Y,/Vc5kHKN*iCf<@jj7.5Y,.UDCo=,L#6!O3>c]7sHel- %J70q&fEoMr]!r!c'H_K`155C/Nb&PBpMr)hl/<[G;gd3udBn&$(t01)/4DFM>.+O9.D".4fsI`B9f%--fe58D[ecC+*KnFPqML@:PEXt %#6\$TheO(/pojjXWgSm5j/BftYT-6bNoV0Q'd%Ta;jB!'_,J=.2+1GlQt*/Umd5P)g:TfI+KO4O3OYr9=H'E:*,#!gX>\mFL9]Gr %/4jCoJeAEHpiR<^2nFbpKhcq7'VIDhZmirtP*`-#ijYF9`+D+aYi>Bo_=tZuppS8BS[cRcE5q2c'[YJrbTVu'dT%*LF!%WkI@*A@>Bb.- %j7Zn9]^a.#AeE\+/8VF_i/^@)m3]`J^#Lef^%@_]8:c+*N/t7MfjUa7ukYqA;E-2=P+'=G&iH?d/%KlkdhgOO;#c %#VnU1!/$6ZZj)2B%m*$"gI[re+WGhQ*&;uX#)I(;(.0:@LG_n=qlh%U)-ncu7Rdo(d)\0PbJB=g_[c1W5JnZ:4t_O[[[TGc8T*m+ %0helpYnKs>FE%gj1-UZ?_34>IYJDOF_[_4=k[FeEdJ?6K-qV-?4NTDlt8>/ZABWD#\=Zp(5"$1 %LG]o[8>eNL.9k\N-tV^k3LI*pYoHLV?0hQiCgATI<&Q=90rVAe@LfGT+6LA]p0ftgZ?
    e-DW)8,P:LM['XmGuM8QL2S1OCaVT %Ah_Df^)1Oo#sh4XQ;."@K.WPqZQ*l9\l]HPCa/0bEnR7]3U!b'i5MqD-A!lU?8b5[%_^XSKVdVMk[?LLZFt:"!9PWX/V[Xkl"rEd %1IQdO(hWY!#@b+PF!tYtYT/T>?*(jsgPdK:`F22Db0SaJQ/RAq@N%W[hS*e+6i+@)9#2O)FiH"F"]2E_FB)AeP^tJ@S3J=_e=:4'C\BbT' %fbiIa+D5f$#3FW[l5iX"q_3eHIZ(V=2auR*l>.PC@@_nfE;-B]?Y86A9tHk2429knkjIAZ2[B9XFBUNAAscSiH5mdNn'MsD^4uDK %HpRM#:q$rk*,>@)8"tH*=0#DG%?J)KQm#A^LH-](e#F4Z;YMD>6`+`^pL7t(\a_VY_u9Xu=gXNa6K+_WC"3`ae3,eRfq/NaQ_eFH0ecg!>bH^*SZE]sr,'C\t=UaguUL %_m206cr)]9>LV\Yf!\q,6u0+//]Y4f(X#[XItg>SLZQV.ArW3g>;oL'@WZAkQTO,0S#AD=\2H'f3QAI`k];u(HruDMD0jtWl$E:q %?[uZGZtn.N(?8\i7^X6+g,4L]W]"D(3Nb9omsqKVo&gus]7$'?CYOX+ptFq@%:L1tQ==[b&R(4#D's^kZ],JW+Dj&$1W.pa %+(f3@`nV?iD&_Z/,Au7kjd=fr0[*D'9k%Ig]5=b$%!gUkbH\P2,rjKojEs-@d4Zd%j2nd-t!"I+Q`<*3D@!R]u<7u %5BC!"bg+&ImDBpHgb-`i^iFDm*?`PQ`>WF#I96t`N\8n5bO*2Fk]3c\*5&r3BCP$XYQKE$j%>4QbjG<[#;L/K@kip&mc7h"F*+Vt %b1n8D3LG(2fO?i3-G@Y(c)pHROQP-e*7Wb-b[Jc`_]7=a#.#<'gq&l*S(i]9]QkI?%,ed8`sgt?9m?k_DYlX'$agLdTQC"7)!]n& %R":ft<5'(7]H-,Pi-Cg9@`\/<1<`#0m6^rc'k#Z'pq0=61%`!cD?bRHD#m8rV9hHt3rkr.=dqdO[gt8+F?A[/@F2-7jZr#Vhoqe@ %gPqr@b@/n;oB/C(lfW4U*F/nK %[hHFl:;,JX)5'#SX?il@LH2*,Won3!LSg/;1c>I*]D2t=bo1QYH\TODV %ir7dtk8gu/r8M(sqt`8'0>IAJlC489rU2Dc^V.-XatJ3fqp5:grQAha]P#^l)uEtt/TZ%g_JAD_`>(_p2;Cb)$.=n-p/@N^^R[Pm %Z2WX!qe++Po2<)m(25!n(Qsl=.j@pI%C;Zl^eGFF>PooBq71O=$?sH:7)oo;%RoZS;$U(d:o`[=5uPFR35BW,BKq(8-q'TD^d*U` %.DC^$aFqqt3NX8<'aeJN=Ipub#"(5h,M`78,k8S'_(\Jq@P67mBW-+m$$:hn0IDW,TjGD8:=KkP38PcVaP#j[\720'Gslo,5T.\, %>=!C?V6jM$a5],pl%&7Y;UQ34S;OA\MUn^BQUj=iRSUpNmU.#o499]4SgE&M4tnF)>1HFnYb*j.6F-suKVekA,\ %fgMOf%Xu(K:t;ZBN-%]O!aE!U/iki1c/RO('CDNe^aPHl(<\?A@U_tW0n$;Lh>9ac4Ij'$I#rsb^m,KjWAoM8.[2C./@IsOFQmQ& %6L$?[F$[J\kn4,f=+D22FjoVUi;Y)c0Q^<[f%ba\@*.`Z2^`S2# %hF#;hl!1Rb)5n&_dW9tk("eIRV/g%<`Z/le#I=V[6anI=CaZg6Nj(2?RVNOkjE#l]'4+Fp*#6$8<@6+c9$7JFciAU[:rO@Ee(+s) %a=#81Pn9q4kpZF-Y]'dIMA'ElTu$F_<`F;!!B/]*2FiD'apk]*iDlNU.^f-N/gBn?.V*=/HoIaH*V")@2jc8*9\:BHa!\#i?PRM_`/Kec\!5o3IQWSGlUP8RD(R%e)cn1uXq3_W:-QK/IV %s$]:Rk!8JR8RcI@?p/0;UV-%nKfnt3)fe>hT:g?lm=L'7@;j`'57HU(F;jno,,_S"V1a.\p+.Dd&oj)qQo\hO_5W4ehlLa^iqYqQ %Qg-hT!0Z>/A^)O9A4Rd"e:*Lj@QHV0)iXh*P3V9W2.`b7R4P,$,n\7Ik3VJiN^HU5PcADXaZr*"QFP-]^-isbbGN^JNe4K(8&-ck %fpMaZ]/(0$_:/:r9mQj4Zpb`OR8E%2@'(TZZtkU`5i"f_rFjNi:7a"]'Q>#>Kf2l$X:r %1Po[OKF#f4=_II*,c3X9U*L/9,Vui;*b-_/u5+^5X%ZO(bn[@'lt: %['NT9X%9V(5d[jW['MHnX!k?]+LHh>[(-aTZO!qE!48g%Z`ET%NTd^.i3SEqZa8#bZcKJ4^pB$1Za6mBZ`(4:TX1tlZ]1'QNJOpI %J?uS,Za4VWZY6\O@'bhpZ^XdtZUhEl5kBaGkJ9KccRBCA+mab^"u2c$,u4S":U#<-qNIUtWT6>*ER<[p%WoWa";`7sH9ArPC>e*[ %K%!?)2;7sB6'd=p,7O#Yf?(@#gdMjV3QhMm_LA\QXFcHgN_./?4u6h__3l\hSo0_/E2"B:Q#N2H-!R1uHR+>j/qHt^*Q#pg^+du$ %5ZT?P$L:+^G"Ukjq_IC%JG*= %"tJ@TflbRBQU4l&M5tb%7'>`pW?;+9o5@Zm$AQHbRdk%T5R89Ai:RILo'97O*Xq;+DJS.hG]d8r36 %[Ns`G"dG;a<2*C_$a2i%`I>#\hrNjd36%#8HF4'V94VaC(J/$-&\6jm*e>i=fLPe26tu&MABMhm//8cOlf(ga=8)3H^I;lUa`B3@ %Ia[HU)`Z\>*hR`lJoFgdT%5iWTkB2j5=K0kcm2"`)\0S8nk=%R(B.Qrd0l?M%L^Zsl*ULdJB(%7mUbncc%hU\'YRVe8:@BDp;R3YpC5$2r&5a\88b=H\;PO"q&f'A,ficCP^Xjf&\,[`n9!PJ[_*;N&Z!9q#r&a"4?>p9@YluMphr=8lH!O\SQGpF?`8i2$Z&1,SH>-QTJr-el:XT7"ZIe5 %.e2sopA4&7UbL/'-NU`$l9Eie,T1%_VsG+\@Ps"_D?+W)D-&l=K0EIrrlg2X79Nf[8hNN/_XrGPQr%gSLmg+b`1gI$Qc%pFq+1fd %e4^YG[%P7NE.q/;IN%*5&t>n?oU5W)g]7O0->Nbc+tD:V$!bW<8ba@h#;&_=P!6AF?Moj2\5^%`/*YaCFaATI'a>lp`er&t(W5_K$RL-KjQ&1F7Yq;9 %Q!%kt&Q-pkGY)lq8S/PkeiFX*'b(QS)H$;A,0:B*20iU!Oa@eH=))3G9*qPgTfdEY?.rQR!=H>7i.?f.");&uCsHMCJHBZfEqm8%%4mVXc%?L9@Yt&'Y7iu,ZG@[LiZ+D4sE(!&Wd\W."?jg@=@\&'MCcu %QVi%9p78-d>SHR?M5<>oi2h#,SR=T6N(hR!K/B8YkQi/n2]H.@d[S9TKkN?=7-':&&qkT610Z$NJm_WjNY:0bd]+#>V,QI.Sj>bu %0^or;]2XFu#3lFI?tu`Eb&fNf1kAhNJ1>c9Q!IAGNP%3g)Pdue&ZZ&1;]$hM.'Za8FKB;]442E*;6ijm,b_"hh=CTPpSQ-%*7rm% %gd'c7)_j&\<5bHA1+TE2apS.k>GB!,RjNnBHfVCN%Q"/D+^tfZ9eFt,h1BQ12`C=[-`^PR]l4W6I;N.c1V;MFXB\MljZ1Yde.Y\l %=_UHp)!=;_=W!p$6u'Ha$12s#)UDB_iMRPS<)T8r%d`g.\>QX;0NAoFWo;*1\h(@jAI"S[WX9!UZ%d#?9nB3;0&!<-Sm^s<(h)Yj %5:c/he28dOC=Np.M3n\\)k+a4$[jHKN4*!8!b*>Z'8=ZNS.aWJ@kT %M_LgZ9$M$abW0Ml^?6,_>R[9NXf_KBp"S*,$YsL(iM&*'Flg.Sb.=#a!eG65?;jh0OEKFc9&EP,R %Pe7+*/W9g+RjI?>9]Sc9bn8V&_8QX=UO\D=*)nd#,.d),/SnC=m%BDPI?Sk(+GtELWe)eO_KLq23K2['ZuJoMMeg:NNt,UfW'CL2 %?9a-M4U2cP_1kAV@Tm$R0?lf8MRd&r;6"/:e7Y&P3>Z7IjEAnTaL)ld[P4]51Z6+?m8L)0>bNqM-4*.!RPq=m.Oq5+)!+oe[?"%d %ggW[)-8MYeMcS[&Ube#OLLut9BHB+WFp>fB4P5sg6769f953R7N7r(jA*TP$4@W#,`B3+]_FBag#&Y_a7qmRG>X1p,1:6184CIps %0t_:]84p"7LdM1KEiA\@Buk?Hno?g5MFXKc`\',mF6TI$k$l(19g58M[QQklQ_LoZB/^g#`K"TH39d9koQ0'uEFFOd/$.*b,rJ7@ %bRWPb=32TK:!,R=8R3Y[_E6@B@)/[GOTf4R!1fnMj/#P=.&d84?%>d %'>/KeG[9NQTIVA0cb"J2bCppK:W&GbXtV[g..JjC73!Vk4CX1[b^n>+Sh4:<_23V]jbQ%Kc+F_C/4'FrYG35+0j^dSSes/P(C1h:J]KYXGt1ku:Rs0\JmKjn1QclHU$? %`R&j-fuF7W.qYD];gK%<1sSV8duY8dVX*i`4h=:i\j5%F=L<0 %/'W"e:(`;PQBS:M=3'A)[cQH3n,0$[rR;&s,9.e@\BmhVdFE(!RQJ*^CB(#4fMr4?C6sVPXU0\d3Ib=%q;Rn?-q@rC]`Z7H'G?$W %abXC+qhJp1(1Zi_Ei.P$kATsIm7%&ee=Lec1-kb;.hj5$$\_GSqIUu1=[q7OLdru]aj%t;*eu.\k@U!b#.QmOE+^sA4>`f_2k)=_ %,^*'Cjo`Ut/V;#/j9(jWY&_fX1YHPmO`*N3Eu]gO=3Y>m?(,I3Wk$^iW98>IQ`[UX.t/Z59snub^Gt5Vji+60m*W'K\nGpn"eYmm %0PhXMHg\MOBc?$s7-_TNH&k^!"5+eqDq67&GYfc;#]jjUD)g9$.=HHr+Ss$ibu>HU>X/c.P@<>_<0=dHfO;eR@1(VIiNqm>P8W;1 %hEJ\*##ZZU<19T*1*+mGh!#okl&18JO/bW6"!44EK5['Ag^,&\lgrEB@dt7OF&+"Pt"#)e!WU/*Rr0I7!#X0+G>DuqFQVm %X]]Aih+#LUZX!W/?2Jn^c-H'8Cm\sX1Z8%+?=CncDCpu<5[.f:[8IF8gi\Gc=qi=hC^e40n9^E2K>4CH$0GdOcLtEo;G75`\QA_h %CkXlaH:'!Ji_#beq\EllSmF76.9hf;X9LID#;:YA^Nh7:h,T@MC`<()DULDW0?4_/&.+UcA?`Nt>(T-"g+/#D&p)a6&k<-27/4"d,oV;5$E'XGLI7BDC0-UG^ia'2B["`o9F'@l#:oA_CNHJ,mA^2FLaXi[mH/W8`\ID %'Tu$h"t)mb.-=93'X"uAa>)=kWn'>%='RQI'N0J27OoT`0rNYK;nf3e4j.uhkMF(K,G@K;B]7@qEI=\bHR92;XMT49R,mZlqU>$R_W,[ie"GWR15SPJKf[G_71[@'nV'3GW,3Wt7P9l:H#!lg+k((?XDlDmm %5nH[N\M*b0X=?Z,pd==C7m/@,qDLKU&bD[h9u=2lD;XR.RdOU)XLsF7">R%'EKC7%a'LGF@>;rY8LBp<"j*DE)So))HIJ84Z$74nA:W5b2hYIRQc`RNo#`sdT*g@B_Y^jX!3nuu[A2JgdVUr9!`LbqeP4U9 %*J4O^g@SBN=kBk^7T9u*M:`7[\!&qG"K>G2g%=Rfjt))GSqAL5MLuT\FLqCjd4F%tI+-l1Z/<5$0eV&j8mT4JL_4k#198!\60@"e %cnaFolk!,?62K?p"EN"7MXPQl.'tY7WmDE(G0sc8+drD2dOV;E#@LPYpKLJ]38B#/,A42&lVap\5-:ZK'UK*Xj=jda_a_cAS,%_f)1g>\1E_CN2,:,l %L4?TP9LZHn)UPg&2;4J--q1;L/Og(_ %>\IF^r+laKV%-#b#B:?l5/*@Ng\^A2/T %(Mk0@'["h!m#Dk\X!P=!+P(nDk^_oq)I-L-FX>jB+1>'[Q+TSG!^V:"cB%S%XJ17R78Wk""Z<*5G*ZhW&2@1R`+d^IN0GXo_LQjX %@$=._Bc`T\*sOcVeD'k7=?e'R&?O.XZE$CU6k(IZ]!YM`UQ),&F,AMB'hkspT:B"gf'Y-i2mMl\h7MTb#;Wu]h3><,kD(5?6Wo:dg9o.o?Ld2(7qjKsc/'oT!:+rZG])@%!YPH%FtRM&eA+4N8>G8*t+Tb6@* %g&<"L7.'8M7aMbhJBAFj<:d8^6J(P7C2h?-JS_>i;o#c!W3+/I9Z9R;h57Jji75L"FO<4sd;1p\c#s]gOq'&Gk)X#iNO;X.c?5'@O6/l&i!\/?0P(b7H"gB9)nBj7 %A0s&j;InUSbG_DFP=^VuhM.LB*p)\YB`:=[!,V!i&,!I@skS(P`)K!aNgVFNH1L;o5QO+tF=.-45TanMZ3USS=6B %<@P#&:I8+IHZZ/u!iN$Wq&I`]F:frcf8HM8?'2]^p*s4;'f>1K/1,%Oi[bSl[Gc(U,PFtB[li\jYB>l=L5qb!5Hgaoc %$e_4',_/!0YVcg5[5;J2HrF6MkS9D*cDgd!M%+^FRQ+Lt][5B1Z8Sc?*IBT@(!ZiTs7(WPnX,bo*^']4 %EU[P'W4"DJY*LsRNWL@R2YZo<0$Q"l:p[*dU:D\h3Vim?&DF?uR^:-UU2mIt>a750H?7Lt2Fb9fT6F@]-9eP3*6 %MXa8j>tsLa;ngIK!8p6BTR#`&]>lRCbt_4iO&bAgXbuIe/cZa5VX-]E_++YeMQl)29'`3G2cQudn>l0/c4>oQI %R*43bKAAP7\dbb&[5D/$1LuANJj33+>nfk:"6bnn]om'@UaUm4ZO\>6OlrhL=ijGWR*7rX-+u.C+!sXU);1Q*l\uaS>S3il(qO=Pe]36hAaq[V#L'Js%hoqEdL$EG+Qr>eQA'i2[hq,Q8icGB"u59_0FHfUqp[M% %@9aE=l]T?l%,u,\)fBpc$aiW`,*]ROAJRCg` %hK',ma@2C6r5:"fk-bV4VsJOr&V+PXSfSSc#:^B<#;V!$m&iq6!'dRRK@Vms(M47S*\cM]G)=_,ZSUSp7J1Uu043@_68g1CE+N]G %\OP?lnl>u93+e/0kHS>3!UE\4=74%\YK#(M:Sb!aP+m>6<0tk;D'W-mY0NRkUZ93A,&#bZ6Jn"pQJ#5SGVWQFc]WUdYsp9'"+s&h %as7r\r((IR:T2,QRA>*$h\'CG^]8&G^b5#sD@NZc.5@8CoU22nd#2jWdt3_l,2(7?kDLD>"D)_7p*-tX>MjMO6'XU[oH&sK>O9nET*9FUXp)W;0jF]f8_4+n]!sAA&Nmb %VCk%7"g&I`cD!P>4:j3_h)"7M5>X1>C)]L:lgCIm5;8k42l9=2r"?Mj%)AQh3E#ZtK4n=I2?mg4i7%hrp(c+k$>#N7S]A=/I#`^aHF@N7o2pCQ)n3dA_4b1Kt^LWglH-;H"e6PbMnL\^/24O^\*FjpE@;'bgaB1@BfenI1%Mc*%e.ZY1i=PCHBE\1(/fE\*3R!@]Vr`M<9>CZe %k,'pJ<%5cOX>;Y+MRZ([=iKBoH]CBP&bhO>j#I:DOHG2IkhL-oY$>(6P3Jr-nC3bh-Q6LAI>)?rQ^e0$OUJpXq(@jHoga,_EGYp& %Iq30t0*eG^e+o+YepuHfX,@mHcKl>6)8P2U6/(ZT@UY-JWTrVb.iJHB._D`A8?#83V*q)[Hq#?W=n,3]gZ]cgjAiuWL2O\U[(&!k %1,-80Y#<=0:=2%]gsJ/@XW(p&^3njkM$2Wq7'UT]._62"h.%I@T<_ZpEJc]E&No!^X2-)%7'oKPF1gDN0o%S %5-r+O1oj_m)'jEu\_4b#i6P@kAtYco"uTT9kQ:0,2W0:Fs!d`YJ?.tP.bL-chGH^2e($E;fjYY:`>c[WKC]f0S>PL8V,boF%I:Mg %Ju@\#T'm7d5P1jtXhsVaC2eP2'fad_.P\2%P:4OCaE1'$M.+d00_fnqckmj)Y%^-c6qVAI]T.a>G=mb@0iO>nDJ@D$5>*T*Jm"+A`+TM]AMrA?+SJF=!S_EdM@+T`Yo/9iN:6#1jp[.&3@EY_da]A3\Mj9L^CF"@GEVV^^O2fUN.jns1>KC8hO]O3bh.e-Jt!M\0m%FBTg&"JMtc %AA^aNbrm?u,/:WlfE%3heUX9OZ-1$_FspoC_Cp`bDE36dcO/er0Zlfn"kCA,P99VY9@0$.2U-cTUQ1p=4-S3TUJ;o0)m+'q-5D0p/s2I?WMbqp.LLB>!)pM8k;>gAX@"6D/S&g!;8,._`!I-fd/ar%0n^70IkkLFEFoKa %^iQioml!s8TR/K14+C:,\%7HJ"H%)j'TafS-d4p\ %j['oEBgGYZAlCdqK3XpQ_#5Tk"c\O8_dOr?2B]tO8N8sp8sG/4]9'8*[>uR]+PTW#$R`9CS#H>>obKT1r3?D-_%WYR`F>])Se[W, %!q:rLGr0]$m^];q.K_a\%23$f#/:qE9WoJo/)L]U(lif9bRd"ECT^4F6*O.RXeE'*JLRt4)7]nte0+rF9+Fq2e@XC<_^UldmRUmh %dlKRe$3%j %=a9+EAh1o1I32GP=T[s-qGH'a:5m;S*7HrV2TRi]lU0H@Pm#47P*Mc%-NWP&SD#hKb$><@QSYZj$EG%8;=>R;\kJcS_N#%G_:t;% %$7jpYP;>Ll?l1]HPO0Jg@iP0KNmH.D/W#Sh[!Xac>d[]E2Q73)?EDEu$fHu5-U>5/RjR\K-jo45 %6":&o);_:.$24fYF32i[2uWU_@!Q9-i-[ZX9J^sio=2%9C[[9d8j %R"uc.!53`M+p\Gr>kWkSE&Z+r:)E(=(91^s*X8HaiVhiL<`0K<..M@+ZO`AJZ>#IU8Ac:UC]S=3Op$\!'kBGb6oS9mjV;2.%*'m/ %nalp34]@Oq8V@\EJK["AQfFA72_)o)T<]appFmM$"LO9'egrMB7AGAp,rCX686\S\!`894Rf`m;E/I!VLKS/J53PC,GN-R1lqfpO %75&a9GU,M>_>U;u97H6Qesa:U(p1,"THo0GmD(id %eIt:aX#_rD&TsM7gP*3hI]D,G=P,HhTQ+(.E?kA=^_Hqc_>J3o_W[u+!&cur1^a:@_/g1IMj#jAUF*)f'N\I!KiT'4[9jT9M#9I3 %f$6kuc@',W\q&/GC49_n!U;XBHn9k"mQML\SR=hO!$2P7lt:CY*1/6K.m=*n0+9-O25rWlq:#X6((rY"o9%IEdRPVB)%i7$oQ,tTYh0RGd0mXQI[7=7[mc$HA5rZ2?LSI?j7s@j^\Pp36Z2Q#P=[/=cmYPTCla_3kc\I8d*F0SR4bM5n(n$G"GWJ)upS?"eh@) %[0d@:,3TeRjn_AAB'uA!Q'Hq4i>XRTi4.i&b)sRkQ(?L8@c05Z"21&:J]M->,QRY(-YJFF"5mb?4Qjd_,Mo&_fs&/a6oP7b9_TpE %#(*Nrll7Cg^dhsi!O&Gj_(;LCT1jn)`#RA0CoU8*%34i1_8`D*/.KW/]pQNZ,RB)7!1<4D=e36]AUP`l;D@A;bdVX`JOgE.B:@pF %QhAh5fiAF:OKQT^mp")tSe8$^#r)>`(S"'C^N$^dD\::jN8X@*5m/6bpj" %m4umoJ5/iRd%en)5Z5ZG<5?k:$EtF/^&XuUm"cf%I4'rMb)HIpO:XBrE73!bl`uEuJO$n>^>["77j!JqO+9LBl`mV!rACB#P1i#' %L'W5/li"5L3&]6b["QMU&lfOf*GA5(*,7IVCTHMm_(\&H%YW.@cZQAh;^U1^li?K+@?;>/<5Bb+&/9Md:>;DPTRZ=QfrYkEp^Os" %c(#8j`id))Y_+Vb9J]'n7^;)?FcdIIC-+'bpm>UYJkFHooA^B-5=d>m]6*g#AM*L-8T`h,gU5"^AOgf_Z/C,6_/ %!77qh#j8:4DCj&=1+6sFmF_b(MU7j>r(U`)4-O);$nD*!pE7R[nR*lr=Md^'*SBFX0^*aKo4(M."@`a(YeYFMitNZ:>\Kt9f,d7_ %75iR>f+T&mVq^@U6=#l^dVY\'jJ`94(9"=r/%mKd=XbM*LgiiW\Qu)?6kBs#3%hoH1*9PsJXpK'L[$$1'o"hg-s_RuJ9J<59]6;u %8#;V6Y3OA^/*,pAo@J\]]%rR2/hbOo++3iZWW2>Sp@dSDig1I:0@!=Ap$22Ej@6AE]R03F(Us8PrSd&4qY&Nj]K4Fbl2Dp"T=d;" %\\12Fqpl"eBcua5bF=^MgV$G7/),&L'O4kd5Oe+bTc&Y?L:"OFBE5+KeR4#@\1B_c\9EsH+W\Cn&'j\+<1e4^+^u1_Bh%'"OG#DO %ZcB-_6=b1t:n%2Hg!=JIQU=d'?-7e?e09#gs7#HR477EhD27f]F\RZ0IK\m94<,:,rZi"PJ2B;H^%rBn;OjXbskI2lQ<(]3"Qo,pl3*&itK %V^ZA%P4dBT:Nk!D/Ai)!U"UnM+)r(dQfW2?FPf %SEVj5Pm\K&KVr>a-0Mf2U%6%WKtr/IP6RujE8Pe)M6eDV'P;c.BV-p@^n%n/S=]e'A9Qcf\i%eSFJqA^;-&An+IQ.Z<9:+(_7s3u %Au;u8MX8CeGLdLJjP"YtqWtNM]-nh$GAn7=7!=Y(8,__<6Y:p@Vm>R@]KbL`-WT6kYR,nr$:+a,TK4/sEFTUOXP=(WJ_4"CT?_9V %6hm`;TrH]oS^T[_Lg;/eKlCgmGGsK%.mjK9:%?>#gU$YaeEAB05<+kT;U-rJ*tQ*aee=R%?IOt'M2k8Z07 %'LK]$3HqeCn3Poq2.fl<*"2pDS^q44%u;%OOR']u.!ZXBe2cdsa7OP[#FAt=Nq5$K#kZJGHW(lB>Q!9NMPZtfiE1;SSYojNIIC&> %Z>sn1+>>G"MZQE?t'V*$NbfSZ>u8.6J(A\kabO30'+e[@@A=\:KB..R%qNf^"KPTXYM(6pd^$.B887< %K$-dq.%Xr;`Db\$99!IZ'l;rQ*E*bP$l)O]Oir]_cK/l0f<:C0%HBbL:T&\uU+PGuOH2cus:Q3@%2`EG*Q`(27;uV=\qIgFRr`RqlEU#71ge@0LEQ:[=.XbZLEU;Q*:@\qLMp %St$$J29sDhOP.rI#nX\-kk.p+3RbZtl4$@*^ulTR1H#IjmZ5H-793S4mjeWR"U5%!B"KH,]&-kT;l.h'NCIdiLoJ(U#m)ulC.llTo/^W9>8R&ZrIG(A_''IXn^ITrm)?_9-5YcA# %F_M!N`/2?B0nl>k-eR@]H;NXSRq.`oCK-8:.^\\=!:5Sdr424P0a5$%MCb=qN]!2LClF6f']W.M'#L!q&?E6:Zs;+383fN&tpi&oaB9$XPFV*3$Ge*=-bDlb`>9i3INkhoWhJ`VWh[>V0Fg)h;a]1d?YrMfjo5`=\(b)feTidZH1A#JJ7oaprgI %dhq=:SO$,/CP\aTV.%F7JT'l8(=BT#/Rs/6QQ-E]T5_$_WZ2=#9>hm`J*RR9]gn>Zd[98_0!3c.Y99.tT-TX%\;>pb`?A^A]ks4f %%L9::;t^C4GFVkjZ#:7DjTM#]p?bt0Gt&jKr/i %^bgbEe?%p"PbOg?(DR-=Kes$JV?&\5_["VS&P3FV=o^.OIm+C;5L%>&!l"M@Yj_K50Of3n\/KF44H&$M1iq;dgKIq$q57J5'V_5!qS%FLB+Sg?]mVr=F(eRLad %CTlIF;f9f-:o5Uo&EYAHMn@e;I^LdL]4;<[_bbfi(1V;.U0<:3^Ca`8`*8_LC5rdC.>aY(P7Dft>>5C!%/XMT@4'/ZPo5mo7Gi!Z %c5k]hMP("2eb1icC1ge1oH3=:R^hRWbW#Lqif.-lbF/lV'sN&ghXT>*>(h:BT4]lX*b)1AJdV@)@1c_b1GsMQ-njQ<,@XO;\7"Se2"n0!V'_*IYL'P44?r`frh>l9W59d._DW %XCa_1WIGuSqG>CCeZ58m3cUidi]-i./CH0e\"LZ5?p7/kTi?9b",W[!G:i9!.$8umVN?R&C;?d`9;a"i)'c2%7'j:bo,-teCcPMINrdC.b:)Mj)LL2Bf!Z\(&IWT>kZV$?+^=FC`Z[#YR\9OeuWTpTVW62m+;*T3qk9"2de %5PGNp@H2R$NPm0-C2oJme*Ou<->u<11ckr@k$W'IQpW^B%RUs#_e)n^,@%3fQ@%$1n0l`"c.SUK3R1@J.Y5Cp-i@T)J1?Y3fVlki %0_!3:31Q#c+:[@)F;A_T"/)6s-l-;P7Q%P)cJfOgN&[Wr+ap5(k]_%MYGU5E7-_65n'*<=ha-R63B?t1(K.<8LD0mSCXBVk`\fsu %;I+%XC_"q`jVtrEJq".i_UaqQ:n=)m!(!0nIk]Am?e*jlEY(=g'RHR:L@e'[e494hZSTDNjPj.i:05DE;OdebQ5X36Q[0^D-ks=8 %-n?L(_G[@coo:n2Ma@7cg]+$@,3,bI>oYrD0N9]M)N/:;BR.1P7`kZ]I*=&Zk0,p=pWd:m@A"WTCTQ:'EGajr1Hq=\smL %iZPfY<*c'!O==QXnGSKG&ia_Up[lG4_LP6dA1A;\3NI-*6,QACg)QL`&_[h)73(XWge_d@Y\lp^244:tY@/V/_%BWWh[K&n>EF:d %6l%KZdI*YNLj-%N^/B7i8L:,X+!'&-'CrA\W1773)'9@UP7cu9Z!(M-eX%pG'OF$U_4iJYm#*AC?QnR*Nq7Uls+d+P#RYn^9WbFJ#]Q8R]sc.]lJJ+FIb %88)[b<#Gc)8947V&nMM\_[Fs!*FnB/:5?r9[0K>=e!uB`d.->:XbWQXER&))F)tML)EPM2cH)Ete'QZU/tMl^as0h\ZlW%]>d#'= %r:,>rI,hH30'O$:.k1j\P8esEHrY*4Vf?tB]!/J?f:_mM5VoI.Z_$RF0p:C,nuAYs(?a)=T0!WojGqLtXT>I>'!7R%COk=SBl/N, %RluN(@KK4W[<,Ru_Aj^5+I'3bim>*(h`O\3VurZ.B*7h;1&STUA\s9c[rpO1nsND5U*?.6]biOgBtC^oe?uqFXc6K-9[j5d^gBuS %\k@lZHNF5TiE>&*RA$Z2&H9`Cj"_d"+u_abHHe>S%51R%StO:)m4agepj+=at,7X,62>P3rn)MM?Y'S8aNnCAWN%4 %d@krm-O3DY3BQC(;^#n=>-Z%c&Xqf>@[S\B %pD73c8)[?D0sEYqRha@HJVrRI#M*cmZhp[e+U&3[8pRs[$tK2]pkR(b?C>1CQ!MZ081H8-ifN'O3.=2Fm>_]:!*&d.G>M[H8gs

    k(DA,)U)!VAkZPMR]fu](;b'7o"_Xt&g7Z*)2sS#4,ATGK5MJb/-5o#$qlWTE?'g$eUfRr+:h.7&W+DbF@BLH>_ANLn&/h?-/0;_tQkMd7:.- %[>aNg@:5?M%1G1S*pF^$(".Kt8i4`)%hO]42c42`J:(@LBV#d,%p8a+>+rrbCrE3tdn0bhS?dYj7t+Y;71"^sh+ %6@G;0+jGSJM_acZG!+<:a_@o\"4]9[6MS,4&V7Q&8=QRBOhZ)SmY@TK?'L[Qc8oPlWckIf_7ge:aX-+t$OaYGI4h+[tB&AHD[@[+&*TgfL,3_,U0DJ1? %!#55GZ7Qc*OdPA9Ef&j=H;l=2kuEYb;LAKsWH33o5Tk3Mr.;aV>mhGhIA_)LWrb(_),B*WBU!IXgA_WdN39.[>aAe3_u]cp42I8m %KJ".0DM?"_UKl+8KNP(rI5nH4c*rAu=l\O.KX4\0#Nte2(XrV%TYZh@!Z@<4%5r/ZjC1m%lAuB48KmX%(m3.iFH7`Ug5Z;d';^L9 %:T#UmSo0X(i9D"H@A(tq;jNE^bSb[R-@#%%g>_C^YhhhrHkg,VqtA:Z[flYtqVA]c+-@esW%nJ^7r2*&C$1puX/E2+XC8^N-3m5r %WGRK+h\bG2J0o-'N9M205ua..cmF&[2pqMG7PPP/OVD]HnuZkD %bp"M!,^0cd-LT"^8=k"Ujab^V#XQ;SX32"[iUXTg"&Ed@`cgh.0`u]$ULk2\C`6Dir5d-X4J7Fk0I<]ZXHW>#=CP0N5+[*a7VNo_ %Ye`('C2Ja@UA9>@P?h(;a/X]b&LfdjEZC:Bo0=rH9V;h`bUe(hga+7284/dK_Wb?@8'4B_e3d):q*e/khAeOsirK/J,Lq1fbbCE` %N0Z$!9\Y-HLd7^dWZcb.UiCNo-:*$Yl4nTf!sU4_iJRMug9_m>d!>is=Q6O1;*!peh7U_[12jab,R)%qHoFhOHaQGC#iqtj9fZO[ %1Vi%1P9"Yo,>h8m/'X\$n>$Ok:Wp@sO=5'':&S@K^^/d6OcnQ-BdE8:,L9VTVTl#-eV>BM*QhQ><#UZnjl\&i"']#j]TIXRiF[F2 %a*iTsh?_r1\Ail..bC?PL0HHfF)Du78p;0]./-P(i@)oio2PC&]V/ab>)1-;;7>2YnD">2=*r'W>a31dQBpA\UCM1V6@t!B#DkR\ %8?>104)VU*l\][,\(\.Sb6A]j)D#2qIkRnp@q\""K"@[_kC^7(G,6106X9?+iH!%&#Vm#d(T8gsJ_,Gu6O38%h@0NpCc"oKa?rL;[)rqP'l&]Sf8dC8?Aq"FM?Gf7 %'HA7>3MU@*;dA[]iOV^roE&7*/+EDl7n;X*WQ.A/5Ir3n0;DF!X"ClD+;-i,&X&Z(7jFWip%[Z7oOeeZPfR=&"H]J94fO5m@+n&. %R0<9mqg&dDn,@4>A&,seb*pO+HmHW_5_Xr';;ir$#l&!HScu6o$AH=CkQ9:lbM+l#"@l"f7%*nG%/F&7!ZJ1# %hmN@>oG[49p@3rnAs]2 %gPU7:<<:1c&IteQk1!eqdM*DG%)?Uk=d(7GHWNWZI;j3)J`&?/[\m.:;q%smS"VI94C;KB'7PiV`\FK`\=>@6U<,Y[Wd$j"/lF;- %mJG2&I6MFs;r;>'Kt4p4=@q2GOo#b:B+>\"0^'Y38jkjB6]WsaAn`,\'Ud;L=bD\PRsHtjCWD`JOM`D_3K>i"VN)Chigj9e2^@qH %2/?o?8)_'p %d:T=LBceBSK<VYd %jEb:4Z5.Ks-b%05#5*Oh6P7J%CE95$a;KqAMJ^c];;__udpYjlI;_$j^`2s+A,tRumiAq9ZiS5+EJ.!S^,/>S/ak)ukD;o@W8Xbp %Wr'Hc>mhlup-ZG;k7Wpp$hV=QBSCEh1;QQ$*$$k7Z/]%tdm`fqYd\j28!IAC[/$+S@r=J`oBO:7gQ[Xa:Z^CQ"8UAXBM,:"snXKE)_bi@]N0e.6'l+d+7ceE=k;MC$,k %$=Q"A;^CDA3%oOLJrpsk`P&H)07b>#-qoMe:32OA2Mde.`)iUm:qP;/>53L*ik`#Q`q>=,*R+p0ipc]FPfJBq.2W[b^h4m!$Z#]p %80K*qW+lf\EZ]UA@=?WD-"'t]#53BTfa[^!?#t&pPt9;\KIbZoTY!k5X?&QUFpbV%2,\qUN!Ad^#!'OAmt5es;4Ts*G"N`nOt*(ma.J2W97V!.BN-u78DSS^iUlfV@IoW-aP.%U;30,XL5SB@88?fI$ %\E3*jFZ=%!Z?0'SdM+)`D#.=o@41GRFC9D41+Bj):QEBg-l]/mF5"BOY1Sfgh@YlIYNj8>SckaV)#,i!.fBBLK6-`tUsQ&,l=-g^ %5Y#KC*$@q3Ad(r9nH@WTeCn)J/N,t7;NX+)!ECIYKOVG'I&V<#n]KfoaQ"(K89AF!MF>nS.,l.&@n"Gc@dF%Zt\QMFrkc,4qgE[V;RW"QT<>VNrSc7Y*M"n76s1N+#u7^+lSC %dI8>n#@C5C1R!k6^8($Y.=>gSOpniumUkajQ7cp'H!]$+0)-F_G&/U_"\MX)]3;1EbWLsc,SE+XA;m%:q=Y5T$<c')qD&n6-Yn*pLPnN6"a#n;*g6Na5C2L&E!=toD1i[+YmYNCZ])R>f[>!%l+X&Q.cs?"TB0V(;V$0o$2F\gA!iF %fHVEG2ms%X\]Nu,.rdVS]INk6X>V9WWVAsDOB[,=H4Q7a0Wa>kV4%F?kU%%3=DqgnMf/2)[es3%rQrVTK#B"R+EUXnf4aBI.P#Y= %0d<91%\M]":sdu.9iOnSPaY6_`Lb\@$MVFB&D#4+E*EsT-`+>>OiJb*fcB<'`70g4F2U);QfsK9E=YcFk0U>)3Z6JtB/ra^IKF2\ %*!\/<(nqLr+D]P='V,X&2.DeQX"K%mbC';k0O^TJ?L8X9`lV[%KK-;dX>3ntL5:3&-@]BoLRk)T6GNlu*rOX@:4@kEHLCrJFT$.oQPK(&3NKHI"\4!9^C$5dfSAMT,=I0',\2qaG4Ke>R85HX,LTb^K %#UY2D1,A`Z*68kW\A_^WH(Y(fnuMsG,4f_CLP!bI69`")JdS>5Z,'ra1m?`>nc/nBkttPQc?tk2V,3c^Bg^s?+fph'5%8b-nn3sI %TfdK!gkKEOJ>k=d(7f?Lj=JpFDYeSk^^>Fk@&[JjXTNPDGO`+:FW]2E.0Xi9&QuU`PICK."VsSmnl13uY0Mi@gC_P1*RuYa6",&VL!6mFAg@18\k@PAtLmg82p>cG\T@iRKA#JWZeVMeUKP8K>%CkG5[4/+d%GXt_nr-s-\lXFNn9-St]iW`Uc' %#l(ud5dm*egX!$5Ki8i`FjpSY`IZen\Ih]hfukA-/0H0PQ>e:70P/tkWS%+o%sIFE[&JU8B5VJ=p6/3.)07.*&cpEg`!$de@u(Jn %DiR&7>c2=8O0V[cD?p675/UnQ,OmD`B[fTI5=d?,Io;r,L/B(j'J[)qD5SL;57-9I"3i_r]1$abnaC&Ed:J!t\5_[F6TdBEM3h&l< %NVrjJI4%"cZD`>3[W7+tVj.3R:^D!f3OOYE>319(i&.Ku%=u/458O[*lDEPTc?0C29X)pbS?5.""M$\i7L@:C$/5]=+\IWjWKX[9 %BUUM\?\7pPP%7H1PXn5b?+iuV:c94DKFsSa@ET=='@88*[\Z4+&Qlt2_kAME3L(:2ics_IF>"#5fd;2#@n/@lp5Qbh:9bpm0e %/9ZM%%`T;H!_@9TcX6fHH:L_.j=_[06WD'2oJC?K7cGk-l7f7g9FC0I2-#=Z/IMGKX=mf.cIk3M3K-Z&0mW,,O,If'J4DG_F3'GI!Y_!AK855"o!Wn%E(RRKcWtb.Ji=-K#O`Li\W!r)\mc8n2#t]b_$DA,2m1>*s#T4Kanj,).S`O)Z:C %]>S?'.oO+pd]kMcqX7lN=3Y@,$24`Q+ZLg;7a%@3aV8WWT@c8Z]S3c;qQ^MDNk#PCcUgFA+Z5,i\;h5t2io7A<:r'Om%53+dpo)Z %F+(!^-C^u(r$-$e'$<(1(Q1b4W(c"e?e65_Fs+s"NlS8G-2N7R7E\M=fp'(EG8%eThDPUJg7C,-2+/=0p!gY/`.Wq`Z8]Rjk8)ni %oX&::,dKnj2Orm3J""qtZUXjca;--i1A2sL;S:5I?na<>aMro?iP\:-WaqKK3!(2b^5A31JT/56#D;4eqH$Nn;jg^pgBO[u6:j#:F+R% %QG9NWUC&,3X;e'D=lE;E-@gF,XUV5',66`cpr2[_$+\6P%2Gu5`Lu%C;P>@\M,@hp;QV63[Yia:#GhWt;%Cem#n=;d-*r.N**%P, %LS@Sa>>9`M(];!,+*#1-='7A'G4%e/Yc4RISN>pTNs^bFK^H`$!E??TAs(DNO)-Rt/rn^E,um)]C(7/MR&)?'7dS6G#eG7BhDT0& %RBU.+A5Vtdd3]<4>@^'So:0"W1-k_9pB]0Nm,LuKNL0^kLe;,iCVlO&)O8q_HL?;?#_NV0A4K]Al;e`D=*3Rp6_5.C`qL4U\oaM? %W07=>oAi;*3"K$IF]S<`FSr>'=B=V[dHCWrJ%K9Irpi:o],,+HkN@WpC(Gah#Quue4k,`_i"]Le/1F8TBk[;8c4Tir.rc9VWTZnWW%ohI%*#a:hKenTp6AJ!K.d:3ZT/)^Z^XdfKgueC %ZIMtUg8AH7..D&qW(*P`:GQ:f=:&I-W^fSQqZ\^W_7<-bH6[Hqqlj`,K%0u,q%T'p&sl*h5:S:tQYt[GG1Dpd'L^H(Vb_/YDW_G:*egq\.$;;eKNIe?'t)qf?7RCB-ZT5-],eHgA"@V$W9(Q9IVSrb)m19Q5@'OPJ!5N):&Nr'SpoYP@D^O)EBc&TZgqbk51A8m*QW-i!s2kb(c'BaOsR]_hC6M %dmS8;_?QQf%5LYS'V'c,N+'7i43E`r7RVd.bqWb`9bAt_I=d/#p(E@lg7L93VQ`fC0;dm=1X/.Q_hdUC>:Y>ZJ.S;a6V90V5KG>ee+CZUM2.)W@!>d0oXRb@gtn"U*OQAf#/Wh<]a#of.sqaW9E5'X8l8t\0Z:j[DOWjq0 %SJ%Ij1^M$+hpC[E55,P23$/Hc0'7b5FOLf(FM#U)j[\g^.FRqJ^$e%,cq-@8o@6R\^58gl)9?H!*jfOcDd/=0/DWgXrG[H:oG5EOh.+Y4;Q>8K%FsH$s)K@ep6rXRYcU1*]#Jkgfen5a?H=7rq=7QbR%g2(A\dMunYsJ@+8t&q_\[I5jq4%aCH^ %WKk2P#AfPEcj?kQ%]Y?Z3Fg0Q6US0LPKBKH!g^uC_R=16C^@Up;6@3LTFO/o:(0NZPGH3-@aVOh#9umV97a)N=dp?)VaT[8-EA%H %k@.=2L\n-5R]h.!&0qZoaYj:D*63_D/1^pSDP7u9;MW*52$hN--VD#a\O3m2.3SgGZiFO2ZcP.QMC`s.B;[Jm9G97+*nB&O2Xc,] %Hs0J5)"s!F@h]*rX4RA.(ptM/(@M%Y]WWm0q+qp32*K %+`uLM-up6F%%0=\$sdr)Hg5Z%ZIZ4R&a;Hs7!1gb`-,a_Mp5*/Z:&gGWMOIVA"Zi)^,SrqKG\V&ikniLF".][n;]Mf'OnTIJZ=Pa %)ZoGrX_=;QQ[3g01Cb#'9Oi4\h['FedjXmqmob5qFq^QK[+oK'_a&2q)B^+D5?KMScm"`b,[Bh(3RS?TAe3&:kUW;A`Md2%oKniY %7;Da7aJd[lS@?iOXGZ0r2rT$iNgM\/FT"3L&_3[0`(L%5+_ %=N]"]$>JXCo@)'6Q)+n3hL9_eR_%"2&5fB,HlS$B#+!ASC#i8Ik&P1R#u43QHRi^p(;o#>u\]i0espb)5BTR)W0jOc6!mu9Wfo,IBWE]g2ON!>)=@:*\&g=&1j7q %.S'$tpk2tS'-_+OJ(kRf.!8RfTY2M&6AroQA^.*7M@shaf,@3e")m4F#`aH<>#-cc1b %6u*/8U/GOtAal+GdKa5)pk/q2RcsWVF[uZB&IY;,$XUap<1>Ls.:gr`lFW-c8FJR3e0/%O+JM@cb_6@-<@Us#C:;Pu=+df#*QULc %Wr+T]g%*KTA`AjV[^(0!E4Ms\#(4FnbgP0"KZ?*q1$.>Uc-A'Q9NtM'.8q7a%6h %e'r%X8u(?Pfn-;2fkXnnY3;9"ZcQ.X.>[o,VW,H]"X:!`n1ff?'HAbMj&WJnmkCdF:5NWB%hQsUTWYQ-egb?)dG-jj\',"g^pI#& %&1b'L=_u.a&t!s%B,n4O.#^>MMiA\G*!iucQ66((ZJ(LsXGKVl`+oEj#N*oK&J--6)bP22_"([YZUEb<<`IQ/2"hWS#=eS3g^Ej> %1'"20K8JQDRSkrh[7+M[\hI7_5I&k.sC#cAq%p+9?o"d2Z:\/#a#jR/JQhjF?dgS9",X`o,;/b#Uj08VO5^?3i#bhi,A(a>40&M)\MC5XS:i*70doB!4l@i<=4_/fTWpjJD&aRZG^e&3i'C2`@\K@\M(GkOP#@l_eJF:m>`"B1Ik?k=:e[TQrL6/im]%Z> %ZidS7kOp>Q.>+-X76#L!9ZY=Sb'M,pY"a.J.FpWAef.3;:iKFgj&60>g]_kSD'diu$u$J$92ZEe_iV3./O<$M3P,=qZ(XanRRa7F %(/n4e@!8D(`VC3JJsT+GnHq7N],DI,EYIL3?m/VQ-:mJrI!0CdN[Q)3#mN.QA0hB"\sXj5,h/`[J1"H#^.]\*O`APni)$%8[%e7)QflEb:V %.jeAHbbH7`?88#dO!iMt8M85Oi9e`!B]\6Qr$Q?4\A0j/R%hSK0aJeSi75\lh717@^baBNO_SSSKEQ%2l3$S)FTgCjr6hKlJ);bB %I.]K"lS=W#!BG,@dZ8CR?HAYEqF`$[Yi0GMNDC.o/4A_^49s9!h8g:b=F`h^)nd!MP?_AgV]bp^)GrJT.gXa\$CRi<@)*],`Y-(, %TG`8cApXUt,%L'hP7;aA`R`S-^i@/UsBN*j'iE2tR[jKbC-XoTYj>)Q,i98A!?1#]02=a/oq0Z@@`$?nEVD$I#'?.`+G= %]'Bp+.Jh8[=r"AkiafQZ1^F4RYKS8<-!3iP-:M'TbTd`Sb?gZldYdn:-o'IR'EYm$fC0o/&]dt_#,$XN#1Tam<__p-LL+O+/GGmV %WElj:_::2,-)7t-I&=e@)26\L0X1!QiRMi]3T,ppXQHM+&]8,0(Bo:=UH[=,7q2k?EX&Via*Wh!_@l6fjcc&I=jAa^;(bX"ob%sM+MKL1W %bG'&mX7B`:n^W\2/\k3\/jb<&B//c**-;K&U\BA?+.IEfe8A/-@"58r@@i,KPpQP)4>LWH3$6eQilC8(E2/@cf?sXkE*fi4*3k%o %c)o8>S,'@=CtB*B[.E5KZAK,(6tdI8`Fel97qq_VPqaB?X*P+97,diP(S%[s-Mk`n5B!O=APgrZdD.DA\WPA0Y*,fg#ZsL5$ %*'n\N2A=9V:@^LL.Y2@cU]f-0mrZmj:Uuoh%Ab5VaLGVH-h-:7;LI8I-?]Z`C[)Rp]:=GU)T.Q'/n+F9D\,nED %c!uYVDgEGcQ/<\"(p<`6dI'.:hmM)%SN2MJ6*.eYXkJT[pR22g$a\V*ng^,)NTTG``jg9)6j^VV(45D:W]c5^54*_+s-+NRW^5.qWrrk%'G5aY?R04EuS#;<.EJ')\pXcT#SldM>c %AE9_PMV?N:fIiG,Zq]/:Xr9>b?FAKCI@B3#k=C4o#J+d20,ihEK6Hk=FBR&7lLj1,D2!GjQ1f80*stHB?lE2t`&jT@o]YFa>+4o+ %,LH[_/]O/X*C1Y7*V5J#N/B77U$U#?$4N76P&4mtYjfs7F_S81a3di?[PD5\EM)n5S]D;:TN.[rX^q=?T4EP#9KqLXF`&4q[Yr_P %0d9Idl<.tGchAgFq`6\(>Y8>kr3VjI37Y]=b\BOXJ]34V8oVp_kNQBrFhKmhN)i4_:%auCNHPs%DeIC`p[D\ %]-^a:G%j?U2B;'a5SUu*]4BS/L,.VNWb#,mcPY0YRgF'C!]GLX`R$"SB/Si,\Zp3=lMEC,dujN8<&'MDg#Of(RX9`me2W]R`aPs2 %+1IV?A^_L#Qt7N8GFetE2kFm"Y)OJgFKd[d#dLJEQIT#A8'n@4rR($r]7+Y`p"g[A52"$O!P=r@No)\^*NWph2]^\+&ccg.@ib:6 %k#lptqfJa^[5"d0X7i#AP$tc8$&$tRJK$s3e9^<"mAIBVmsRDIVNVH_Z.m\I\f"OU7k1^LkDtZeRA2':D^GbImd[OY]rgjiWdV?u %dl'r>ST/&<*9d\Uc-.]Oe;!$PG$$,s3[pBmeG[sY)7QGn?g/l$>_]00$4,=I,_CB:;kaBkHHTJ8$H&LY3JB.058uQap"FY9_@bj#4E=>7pUCSMXJM_Yi$"l-2_]OHeddZI[Y6Hq6D((""f?R4 %kIB@M0NH"pMsDZHp6mc4cJ#em&5&J[U'e!/ilB-Vj+aJpBOB1IQeI5DkasYe3q@ %rM1Ml?ug'eDr^#XY>I$C^5J/j)R1kn\?q20,'Q_*]pj)?L@G8R65L5RCokLqJTnRBR_r,fWIS)RZbgmVjMma57`,P$iG-reS>Lj5 %O@[SjP44o91nRnC@a+3Q*<"#i1N2LnjFPN4.LRu&Y5JsMMNF.kH0f>PInEXhnd6fsjN]N]Y`+A#TtmmA*ur4@qF4r`,V'?*"+NbS %^9+K8,5@%.^Q%caVsYZh&\/#mQfX7+3TQJ$6hU4:J1>^b2%)XInMW%tV+Me0WrtukjOL)eTFMNbfBP9h4lL,!)_=iG;2n_t=)ba9 %=Job$J<4I[->+.G"Qi`!+aS1u5%&DM+>--oo^YW.J\C=K:2[td_8sI\94<%o$@R6N0V9d!Nu3\-ilZ96$HfD0/ghZQgGXU-gd^9J(+[\H^pglBOei?i!+2WSj\c-<4B2i0W!-KGm2SeA%!DUfFdp4o8P$:bKo %cclp-B[!7.7(YTCYWK(jN$!^qAe1OoZi_9&nSC!j7s)otUUXjb-jHM'Cr.Zc/kZCt=UsVN)6%=I3::@SriN&s%f"ZUqNoB`cPAn, %G-Mbl%b/_`ea6^+qNi`1c(r,Mm-N9nhk.XXh9"(3UCTON^3jq+qrmn,c'Q%<%PJq=W_;`s846g$[eG#M[:G4FVF]bf>@^hg>"l't^t8Id?%3lNb9Z*d[b?##^dXfu5_8FWelYq=J-!fIuujrTrV) %ic'+G]7"gAET]o:ETck!?iP:0K"oR,I!'`.k+4du]NA4qo'G_"`hI+ZZQ=Aj(FNQq@]OpjHf9/Wf>l'Q+)?ccHYRJOI*Wc!Tl4%V %;u;C4cc[3[rTc4Ck9nrl_$,IIQ2!I$d_/AN@#RQLj1T7EPE&,l[MZe'%?`b@S1*T:RX_!ma+0o'l9\V[(`J1QM9)_n3CU;B:iKp %^V.AZMK?)R4I;JI]`%chk]0P4NgILc7e6AsiM)&j^H+J\Af[m\C2HIrB5W(eX(;`)5P\dQ@K4'q^%#$nCtF12o:9t[^P$@fe'#)@ %ldJ'U?ZaoR?X52rFED\Oo[WD+DlCS5bt"[EbH$-kjXF7/?S>08/rrfF[Jc$4S)lp5;?+d9CD+9#G&fBf96uj6+/W+j!P);:pGc3: %XFM\5=Q\u5]1:%TY!_`'9)nqXq@X,u(?fQr0cqJ:ma]SLq8pVCG$=nA2G1NpL5_+I4i79rD459#r/s+?gr"oo1GgI.M^[5r&97kkaqj$dH\>Qdt]6_s=K:GIPcQ^"uV?;f[<]NA&\=,H;(.%kh6IYK>X" %s)rX8\of$Ihhm%N]f.h#"o@O'eK+qXqu'g#:J1O,o&$*mrkeo:=L(m/?RGh%Y@@m5MK7YdP(eo`g))TR*\d %W]s17I(o?`I$a0Yq3S#2QX@BdqXX:WNUcu((k521s!R!lHs#fdNqqHn]tD'=\\>U%pHN$ano4?bDf_PS04$1)pRZ\4q;6c6fC,_U %s4u=gl(7j0r4qR"%GC\jD+N_OTp?C[Y%M9;Jc6)TrJjnlJ!lQGs4=h_rdHdu=nRunJR.geBk@=eP40:>QWLf^?QL7qrr.JVIeE9n %lb*`'lZZXbWMuT3LY#nHB'q#.;%R;i)1o:4(WmSM0>WakH[cT_mCQ'Kc-b4PA5_/s?X@(=BtMoUDQ]&maOGmoMmHL:gLji_>oZLU %maj&&kjWf-?52a1#=5bsXq"72J&"Unrs%1im)A^fk>/oqnRID^l'!Y\5E(iC9cq'h+Hf%qs0,u,]`e=H'"G\,J(#G645:Rbl(7Ab %n&jMdgIU29=&F6iI<+u1iUQ@&o\t'B5=(G-f8pbtV3(FY62LT]=Ke1Y*0UE#N2b_1J)24@ofgst:!VgL/>qQQG1?97"p>Q\L%sdKLTYRp>i=k%RrW`An_1.j-iWSJcs83aIj#;I6 %FLV4rB1M]ol[s[K^")"fkBlWLk?fkmm*<0Zl5Vk(*-U.-mo\qnO[l\jT,r<(qT6MPo+(HOA&,0t26mTnKNt"Dc`FnWeZ1M*,jkP@ %L2t1U,U]H":!75qfC,pCnimp3I`,h`Y[:$rcR->`e0u9>mDi$&G^.Wm5"?*1Z86$6O/.k#.;/g=4$A"6p6S"Q8IVLhBP``@$Eo:G-Mqh2=Wl1:tdTf1gCRZi@\n-72i(USL(p7@gm>F6gO5L?gVXQ %DO<>[iGfsfBL#)d\cpXGUtsi&CqI6KLHak5S[9O2b]*hg^Q`d>g%ERCDO[hZi6u1cYMn=N;Ik_r=>]2bAtX&9c;odII.)m`9iOW_ %U;`X8TSj[9gHKDSH1JUnGj]&5``XXhB*qL7?rEZ_\'rE/XM8\Nm1cop#_YM1sP#LgZ'$uJAN %C\GKU?\d5DgB5s"amGO(`CS(I)E0N=&DY#TTrle;gCr@d!"t@!00BW`p4Xm;!%#9u=MZBmJO+i$(a %(hDA_[HTU:ig+>`RG$#7D)6P%A?6-t]&HHa.dbg;+1tD(7+Aneg.+YCm&_`9cou#C:OPonT%P(a:;sS!a-qRk/A:G(2,U!`ekDge %f^+?4LjQgR]s_-44`\%'$J]frj!2,>f8)WVHJ8m'RKSaCNU*lQ(*igs/fOd>T%R&ML=S:rTrRF>?2tT6m.B:]J,/R!h-^-d/u?`! %A7hYs@mXPo)tt5iM?'Qi@\0*\IA?3PrlppfSA3%)o=GP/D;@GS)g)+r^]!9?0@(FRjeg`'WL9a\kPm*sXn(9Xp"2sh2>C8-Oh5BV:nt%;\&*?I+^0N$pJg?/oTo1/0h1H,GLbQY7[r?o+kZ.b %WR:-h_E7)pDqVXYNW812Y7AkgA#Ja$55G6q`N%:,-n!'d\QsDPgEI$Y33ACRr*QYI)N=o[ZPpk2GP1FB3_AX!b,U?&mq>b?[!>/J %NL'5XX!KR'5M%4PfgjC$b+!F,?6QFo2$oH(KJ)H1VG(]"^5;4TqX396Z:E?$tRSn@_apo7/?_'A]>DX3GV1MPDf73`=KAM%OlLo8mq&sX.dm'DY %l#N2_h::K7nc:\IkHE/heMLIe1[fIp&Z3_->_>eq'o3YiH?Jk[.;m^*4kgtT&YMr]lhn8*^Mmf6?P+0.7q\u)sMp%$BGF03Y$Ci*NbKRnghp]UC %[bpc;o\t*5BR5GP>;jMG66n2?rdEP!^Sg2nN\cgS3"tcQrMLbFJ!Z/pelDZQ3p?V5ofF7<4Sg;kBRJ[aX..keo,h%srG_Z'+)VQ# %U4cRO*3j_DN^*Q:pHRWkpd[LP2eT$YJ*XE8@-Rskb_DEOp:@I+j1DD]++J+cbAo.Pqij=XdoQFP5:)m,G"nji\XYR=h45qaj/(L>tPaVVFY?D"qWZe&DGmJ_$Q!r"k^hXeolf1.21!UTQU?i8+?oOAEj %r8dS@GgV/XlT"%q30+%1fNskffj1)&ms$`gg;Vt::2_c2%W>-d0*$0:cLN`!V9)fK3BfI6q6G9" %X4uIRlcW@2HF2gOhk.Wo]itF7c+W;"cfOlsnD`TqE1,4N5;(c`*q+!8qdpfPjCZ'E5I4#+B>/]D7pfSp`4EYTg$>lILKsEBqBtlH %!,m:-1OuqugBNc5eq),Ul`X*-^HVJ2mI$=]VmhF7:+SJ/MD7mL%js'ioR5YQRBDk0!AaKb%;'*nR3+1^TS-pl0d6Hf-b5* %a3j:gB^WZI0-I6BG=+d_c'ofhMW%okI<'`>hrW,]h=a\6\'*sKq8oD]YZAI!p$W]1i$Y_m@7= %UNY@_CiH:rY,8h8e@TATQ_-F]+lKk[h8Z"o/&OmF9Yknto'XDFC4/5%c><6dVq*f?IBX^4PP$\Wo"3']O-cCB_/WOuh0nVsFhj<6 %FJk_`h8aEI3k]jEbii+mHfIc&QOS+dF)oC.@NjsJdfE\O?^EGFl/IWE*Br`E4R2fN5E5:&icn#b/>m(]ITJ"OJns7&sC`[Ce`NVChDj/$2GQgiJ=$5TDSMdm._42R4Go)0Xn_j:)e>!Ja_\GN$[I(T+84+=g` %If7mUJ+g^,]q$E3peo'5m8ro2r2naY;hP!&N`c)VZN^U+#n`BnFc=+UV$HlbpW8^pj/?`2X3X#SFnaW$ros6V %]9L?6&+VsGXt.9cfpbL?FE_kUq8I'2#*^8PZl]SZ@MiHm5f\NPk/KkaEI69+lE\p&;VqfRrJ\n]B&?bDX8$X8Tj>\[4$Vrd!g^ %Rm$\hk72E:SDKhZ^-V&B;*AuKhnS[='u!4HTF1c-H,EJKACKl]46,N6G(smVk_=#D-p7:D,"*ZBH.a7BH&>)0[]e!7e %hOl+_^-,oDl$#3R\tF>!f%#/7h^hEDMZe0`j`,`O0?'^0ObP3tY7EfZFI8&cM^A+`a0%A/Yhu=*^f0g`nG;8VPIkQbbA#\OLNe!Q %M26A#p3KNbIG<4T0epE9najZaYAX&(r=0@I;8:#TRo-rt*gq7oh(]EUZG$d75Z!_e*MsJ!lKa-O( %:VM2m0a(cS;X!hGqrZl#jSX=^L9l)M+1t4A#heX[\U".CWG0G=G'*`(2p&f,_9:Rd+82se(lrUK/Dns>p_G[]_$u.55PrF?s!7lM %O0AT`p>.n^SRlLL*1N(\96>1QqBba+1!Rl3$$rLVo0S4fWRGm=V;^h-!nd].rULM\iVE/KRjDG0XT6 %QZ%)pPpnj)s7(*lXC#"%C"BT0oK0nP]=m1TnF6[$4Ks4hHN!./Kg6Yajn[5ch!*i^c2#@1>En(TRlZ0hJe6N7\s']H'FL#!pE.hA %[!mV"9l9(ZnRI.m=s^t&5^d(9oJdaQoR>Q.Ig73*[6Mo/F(:$4bS8U;'Ag8JMs"R]T5^\='RkIVeWjtOnp%?D#el7KF8'81_"9L< %c]VM?Ii)kLcm'JBG[8[W7GK;._B$8Bq#H^Jhf1VJO-^ebRqSQ6.ujIDJt(Cr5Rk_7e\V%TPm2I05soZ'Sd_:7OV)rTK?h[$oAQbE %q@PtafF(cis]"NQPJ,e^3I!hUcmZ"r,.pr(Y5?YgVine?[n?l^O2lN73naLU2n-eXm3N!8) %9)",0`,3VtPeR.mTE"N5?g/*b:fH2f\'R.BID)Bn*qWfZQ"pP'g"-T/L4?9,VR-jT"tubhDWMg(;#Ht^hF'%]HN/TJr>lE?8%h\" %gs/udK^1,j@(HsD5e8&@N'C-%5PJ3)'MPe8MdR%Pn]sm:G'P(@IKq+,Z"c2oeM>,rm8n]^cVLT$quIa,G["6)JApX1`0m'p",K%D %ep,F&]ef<&;4&\dUqcUGioq;,3.*pjICnMYe*:im&"^%14YH;]WV*_^UXr:hrG9IdMGEurnUSF3R?@Aj\AfQ4^5LZfd\;`&2UX0e %Dq10CJTZTs#?WdKr+FBcm2t$9hR32triCk@D!*Y+f+g<64J8/L!Uqi'BeG+ASVQk+9KPZ!eoSj;Glrm#rU%(UA!'#CLH2[>S8+i2#q4 %00E8kRHX7l;!n5cN$h]mOdpgPpoV9dP_I;&Wq8;fO%VP^^G!]\Zo4mbL%VeCgILle'WF8N]+;'8Xip!ngc`6[/p/Y3Y4nU?pMr43 %XnVZd0fRC*-EF,eU`O=DT0a-AXSP))$.YrC1V*E\r&E"cQ!\tj0CgE)6c]-pooX+k'XtNGB=&`\H!In.^)b(oNM#K2Ij\Jr.rXaM %PP!QFL#K\rT7eER>:fSPHPDNMPo&CsF/p#62j3;$e:"W)M4W9KK1Vfah-GB\I!k:oj0.'FmA^%N7qS0*:EI3Phre[7R*+4^!3YVH(BGMjm;c!09%#sf]7C>20sYOmZ+o02Ei?$=(m`@-I'P/8Crq9BBF]J/].%2O6SI %QNdM*'>rqs*C2RHrbXs4PhmHSSa'FbqNPjqe9\glHo:bN!O*E;ad[eDYYFIS%8a=G(PgQaQG^m>6BV+(LLG2/o=J2km/BbW;/YbZ:H!(l_G;i%Vo[!(,(A %+J[a@hQ)Fd1BVVRl@GpSdFWJgr-4T<6PXD0`0:i3j8 %"u+QS(2=\XH-2ZeVkJ7IpB\N3^Q%^4#?=K9$MtUlZ_mg$^h4_goga7Pka0]W_jk1^Y:)5PfJ.A*)jQ[)%KFs"$\@<:mnICMEl %EUi_V$NA0MA$^H0,J;mL5Kdjm<^C>1gZG-$/YSlR2Ce),q3i0`j9i2[Xr\O3DW@5@jA3LsQ*0/r'B>!49JKQ^S-t8mH %0`_"\-[\1aVup$R0NL)7NXT[8[r%./EUkjcKZX[63k&62Uii/g %)ctI*aYYClE>"KgoM$"jA1i\CRPAKlR$pGRN4)H52\%G9#N+"o6I9WP9&MV\bDl]Q.daNdBTWN:@*8\0;ZFh*&ER8_qBkWX-)]h@ %lpXiaL*BAXJU_SY_C&"4bS-rB2dWh6C?_d@r:JbGBEp %o"4Kr9=D/]qpUUP;2othTu:s+%(YR%4'.uFdQs^WBR!LK@$.RIJ[cAA06=9+(IR&,4?Y==f=T)Rh,31'#%[E;8n.C(Vpmah]%#Y! %NP(#jNUahmUcEg>W=6fC3b(Pd)?5L9BY6UD$X#[,)76D>8)og"lerT"BC2T`]kj9E^%)\b!X(c!'SAb]E`u^r?95#dhp1X>YA[<^ %oBA(%$sme&"e6:pAbii#7,ZLj=/7j[-Qb:r?1!71s7bLZ1R^RSq/=4cH8Hck?nQa@TMU&3a1(:57ss8:gp;WHjX#1LahAP]3K7'_ %4P:p?G@:;Ah$ed-Zk8r1YY!1P_t%T112'UXf9fK/(k?jb&fV"skGA5!2F"e05/.7tomP2e^kDR+qYa\cXYqfm-O@S)*5aXe4_M5o %iV9fbBVK:0_rgnpp$"34j,S4aV9GB]a:c<3(DTO=WsIc!eM6\"kV(kCa&^N*P-kON'QJJ%l;\c1as %K;N-#Z$kl&j$9T6*dc!R561AUk^I0)P2"gLO$5g!/oJ*M>@.%N3kDa9ZeLb#'O$G+H2Qkd!m&c_obMA5TG^HL6ag\u@l9W_^%PE,SVeM^=J-g>h-^gu0l" %q8ha?4/c,$fI];897Lgm<[Vh*`_'h;t\;E?qchW/!]Pp`7#=i-b+VWK;!"cd:E^d5LpXl"!0A=\?nKqD-`noM>9Zi)j;+!@[4 %-0=+_3Q!be.BO%MXE<$Cde26hNJA^<8*iTiLGQOrlmm\#T.YV@1/G\=n!?oqGApF7r)VM8WEJ,BQ(oMT9)k5urVj^\oIH9m.\g<> %l]m%n?KtL:D#$G$;]%.[o30?Y*.;LjUM1RL@SSO"WtP6Ko.(B@l<`_b;uE'GNOkri8&q)A+d@BJ!r)[9e0Z5-NcJEpc"f!I*`b1"Fh'@#,T/;n^nBY=J#B^UIqgfunHMjiOpZ52caMTo@H;ccqH;Ucdk`?F'\ci %hqP1SDrMVn*?6a4^I^E*.I=//[,cH?&aRWVS^QQ:M=KJoqV61_\FHWfYfV_h7=#s[<$$m?hc/6W8q0K#:Q6P3qFf4sGRF4;ALN1,T %bq\M39XV:7=u"!Ol7m5f-ANE1,4g-d2#hm#LD)*P6J,677ccmUpj3RiD8jpTT8:I#E%-"l>CFJj(pO9q)@AAiOa:j,Z_YsW6"M[XnNi_$$jHHuD$3"]U\'g\Sb:$4mIlZ1q@#F^t?E3PE1:Hm_&n9tO>&=+UK8P>),)[>:/dVtP %E75VpUR\^7>l:S]g'&GOm:45m.Lf_p'%Y.G:Jr3LNu$E$nVre1(!6D!Xgi-7UiG4H1i=#cQhQ?ujkk7[#,km6-a&961+f2ei$93`Bf$@[jE:VH-t(Gb)mVB)B4?<0+F*Wg1Z$8*9g(aT-\F;j/;)cQP`Hjg&Ba[5q'TM5FF9.m3bNu=1t+ejR.<$JiTt8r_Q#92A+5mgYV5>4k %SJM+#H/'_sTUS`L)]LKHS)gFW%K![@)RPh#P5Qq7XX7B,k#j9]&5<4+DprTBlL,I,"gGBE,M+`c,G,^[53d-N3.nco]EY.;POn'I %lZUgpps`'PNM>V/NHF9>E4cdEkpHGpmT0qNjB"6^g+.h#(+fQ!Rth9GS1,Hhg\6TGY551;eLhsCWZ25kd& %N(k8$;]N''n`@f@cEO:H!n/& %4)hg7GAEkeT-lO\8,5*tLt!).i*A`Ljn.\Ic:O?s1nE"\`G#oCA6]j.Db`N9fe,k?Q8CT_5)8Xm1o6\DK#u,9>E+]I6!8I$pG_EO %NLKYpcm?KZ\1sX;#_/aE-^.<7nffm9%Q;gQS>OeOi*JWkUr'*-/+LCPALIVrdXAV&O_-\7MnAG)_DXj`W1+45=r:k'1(En>cLR.j %_l=/fI@0T[qq!lhd]2`,T+m,^`07NALeHr4Mh)+Pr@/P2&t?;LUNkX]@'u.5XUi6q)T(#k=,SaC_94>L6uQgS8U^ghRon3MAEA&6 %fn82:l_RA@X$ld*MchI/[*Hg@eo"i5/*2gX3S4')ks%j)*VGI9hD_YD\8.?qBCFo^c[<^]3Y]aka_DpqZ(hb_D3areR[PAb]_9]$ %SQ2:NBiTR7^9rmilK=Rn2suBFK/i`$R%r3cj2KqkZZcWQ?af[j:kU^q1WkcTK3#=6bOcUd0;j=Tq2F3/Wr5Mo>8ig!,j4KKCJrc+ %[NJQIP!&TDos^+ARr@u36Knhu8e#ie^q0(HSY\Tp=2tVtig]?XZVfTo\Ypp!:N*gK]r.cZ,=uhIJg'5IFZ96:f]#M=5Ntg[1!5]+ %I'h@AlN4Fu^0.XgCh0EU0VB0K#Dq"Q-`aG]6%8271lOWuS7QDd41\`#aXJa:_lMVZg>hm]#X%hQ>d%-r\LaSe9loC?ViSi=]l[5a %!;="GBl,]OrR(]dLgEQ$L[+*L6=aH%[Dd8UB6^Gh@pCbU8QX:e`EPg:(N]/"!)8F7F9n'_G>6`]X %n_RM4cM'Ts?5/?r>V^d[]nGFL+3AKeY.kX-K]Df&R;d203shhYcE#n\Zc=fRr'd-7#@%s-'#r^O&"oo9K6)KKi6)J2J7eSh,eL(t %,,4mtC#0:KUJ[`ZebJ@B4d>F0N_4g-#UGS@Zc_QY[TU1XQ($-EV;Bl@cAUB5XYG4:qoL\`%kGYm#8C>s2($&?i1?]@jf*5?/fi_j %:;Je#hXlZ6a.j5*#'>WaQa,@cZLLj!a8/IVS3GWoL=8b`$)_+d3oP2V6GTS>XA]d1a7u^Z-;)l916$n>>^pfgBH4aCSic27fb4MAa.19Tk*!Gf(d0),qFoT6tnnH98^K %HTCU51k.1X,ecPb4,0SahFa,i?@t/f4s%"rmXoD2YJtA6MaPOX0FAio-m(&%.Ta6"K-iN!Ke8?OV7!`!jhBqBW,QaueB8I-8?R#> %XhQ=N?i9&[gRq7=l*9J5kQWD>e/X,#.,(nRVU65d\0JN_F37KD%u=P#kX=l6oJ:c;gE(uRgbJJ1VrKsS@m(okCpXF#Vf$Qe)FmEOF/Bo@E9;ia>.]6egOs/r5)pCW@iU`uGdd(/$Qap,P#ApBj3rQ\/VX'o2g\f\D'^0!J[Mp1@I0=#6gZWF+#"iC[Ye9If$M.[NcWdqt;cjk"YHk/C)i8B:-kj4a9)[ %CkVW`kI5&cVk+99&=S21n9R+sB%VJ'GRE:rDZM7Orl,qOM/B38UReX-!@A=@0@Joq:XeRV@o'BXH#R+HVOk81@nF0C'FFl=Ff_")U`F;U.C*.ckIs#p5adCWc64nq#0W %F?IafCODA"UGUU`rVj=4gAUB0neHiqnpEd@*Din7>=SP(Q@7"B`'FH+CCojn%W0@7[)ti/LM8p(3S:YdCE/R`j()9^,n\f;&)@I* %0$_-8?*3k-SqAfk:AMtCpT8K?a8"S8YNIe,^!E@2Zt^Jc^Tdh=QoXMHS4em%6$W]eL%CZ)VES\R_hR$uQuu6aADJ5I1q@6T2S5$f %=qHYJjtS8PP7Tf\]+6Ar>WDut7;N8/j?*YnZ%M54(ch6%"s&dRaaL="j,_L!#=X-\'>\q;!9i6$bQdUU9^GJ.#"ak6P %]P#C$f:0X"4&Cu)r/eW_[0>0JbZpJUnQA8h5(Q6fH<&A&^NWp0rZ>,m3bD*C0=%QU2J)f-AI\=?r6Vq/\%GLc@2HtMgfr`V@u0': %07Qm,ArUd)>qls8rua>JX:DThblsjB4B7=[lf9@?]\RF!m57WLiQmL>p.t/4ibpo!FR\j$Q*&l$)j]_,\I/PN:lB#eV"TNW44NHF %eZh+:i4t3ZJOU[m!%qnk#1X"Y!t;`blk#78N4At#]OV&c$-4(]7)@mj^I@6P_clfV!Z3&Kn1J,S2\\L:u*FQW2DKa(9#?Co]`! %e1=W/-^S-IJ8/\8R+Wm8a1&e=ESNPOFNhm:`Cul\TX/Z?UUN*m0Rc6UCI0Wl#'e1+,C"DrDmVDB^:K:teZ=TCNQ;$OQof4:bm]%s %ZPr"/317cFY+7_7K6HD*e[I[HHd@.:ak['n'3+CIV%+a?_RmD>6d*)5'R[U-PbF@O*c06)F#T;'bDi$cLm=Y.Ns7^@@S]WPbg11, %D7ku\a#&mZE$[[7I]q$Z99R@RPV<_TrofhNa5uRh4:!?&PcZ*ZaW4Z!*g@t#O'BL;!*MU=;/a# %St\I49>[(PX'6-F:V#->dP0h1B_0%dUlOhfR,>cA,B2bekI9J9HH4T!5JZmGF:/t,=Nj/!)n1C3`\]Y+N,C%JPTbLbm,m]q,Jj_1;+I&(f5ae;L!Wg.uI*4b5A;8ak,!utfkC22\e8Jc3 %g:KV4+^*5M;r!%SN''e&!+dLa!M6b@ciUman,YY7)ViU4/*uZ@\>]ul!IjaagHQ7GNVK;oJ3abd;nMm\5H@ %MRZ1+4Ys^gYNJqfK4IN#Es\JN5&oH'PcW,1DR2/s0IoLG4!b85@kE:#WR&1qa,I"fgYL.]d.E&),rn4fJ!`[r5.`L@Q]fh5fUjMO %[&IAWT2VU+q3kUHI#XDT9k0H1ftXTV(X='#3a?BJq_[<'9I/GLJiM50jmUbE3AWuT[bEt6#uOH@kB,W&@8R3T,1\C-:\-i-E>U_Q["ReCcGPu;m+;d' %9KQeVAT9>';\t.mf:nS-=SPmI[[8l,4]_o)Eq9%J'%SEKLS&J8cFtbH1gbs-H0&8dZE9gV:VIQ)RnNP33#..%%A]29Gnm:oO88M_ %$JJ9b&SUBs39_g$PZaj-CS!_1\R4rB>r.jHs5o=VE:'aEk/c&HS*a'B)UQlC_%B@4b8NR,M!5Ql,\3SdKX %BN?YGctF!%LiJ2>K=9QSIZ/T33qe$N@hI+bfdh_pGiklT`BK"'+Pf20n!A[Gc5-0CT@d.`)-3iJ]!iA(#5n[E?=uX3KH3IVT>6:E,C4M$LCIu-rG<]m %(j7dMYVifA_H\YRY_>&//iI>ViNXE&!e=PS\k+`DIG$YDehUXcB_jXd5>q!"K)ERm*3d\imheVG=^(kagPF#-6k:ro960D6"3,]7sIg)BG/\"mlS`cZAK$NBK/Q>+#?U8>,(0mYicG+tV %Vcn&B)ERm*3c0Z;_DQH7mu^6$-.L:9$*LC^:6-qAXeE(tWM_60OHX>.d+L?'qind>D0>C("7KM%oJ8^&DOFf2C=^Dl]j[R[.6YX\ %egC<71[J,lmes^D#6JL`ƽ-21a+];jRDD#>;LN[bupX_:kDnWo9[V\gu3IQZ@'T20++p0e,o+,O?:<6bZ=T-nDXp[n\WqON,( %W%1F,Q&i7,=$@b;QHV?=\RlT$"k,?<2+R)]CZk2G!ic@SJD5,q#iRMibojFie&ItX_c(4abZDX1Y1NTbm81#r2u?@k\J'VV;O5i, %_AQi7G4X"cfV50E`GXNrs,7*d;d0<4Ho?UZ6dqH3#^0d[B!>;C#O9OI"fq..%38S$[oDnTFRfMmR4IJIgPk*A(":E6+,S$Jq`)Mj]J'nNqP1&m,2^Yr\U4K?1*:WZ`EVYi'KNph-H@h3t6IkK%&VaUHbVl.F[J!h220X6X#s=K&PDoeuDMb^9$B%iBBUpKqEfpU:eg^Fb\kn2g3@./;dVKD.nbW$Mplr9CR<:2CR %RT^U!M0V3Vgh)Eo+@E1HnjH"+r.6:Od$:uA]m?EjcZ?o/$2tSF3Pm;]Xo,HhaB97)1Of<4JF]+u%&S*K["W:o6p.;K"`dA?j'<8Y %iF:%"O1jo`Q$nYh)BDK/N3m4,l`e-7oXe<;YI;9I:7n_RX&;ou3VfHl.8Y)11c<8%/#:`*!s)F6m`P/_7:(Eb;P;:_> %9lFs!;>DKX)b[;>M3Z$,%8P?(=Z^aIgd%3;uHFUN3 %+8\u"h"344XGC)(4kuZRW6SBRkHdNuM=kg\WYV,0bAd;G:sU>g"mY'J]:nis.NY4jI#HOm3R/Yq.cQc!k%:`NRrM'9P3V!mXqbqL %Y(q)<@U@5=NUC`lQ1\hKB$<=*Sk/(fWB<:jb5cl5Tek:8SU#FW-V>`ei_t*dZ71H\Edj4T%g?Y;b,'U3Xs?%Q+!=9#W$SbYXmN-K:QTYe9XPuDtVbpJ0?$:c^%^rHFD%Te?`^cUgF'P %V';119eW=e(&D'*74S#;\GjHRQ;Nd%eSE!]JTb(t\a8WL!V&0,Fm_snTH5NSm:($)1RV/WS`D!@d8+dZ;Xq5&%JFBO&Agn42( %G)X\E+poAm/lE$h3J6PNf?u9N$9+5Mpofq!\`UqaD7]oIl(aV^-c-+na;<,2'(_\#DtD#HNY_WcJSNifc[(\3@XnS:G4llNi%,_b %*/=sK]sqHNULOm?J0c2Mds4fUBAH7Q1!8kBAik?"DfG7&JP,1dAfaX4]hD2pE#HuJ%smSe?,jLm:Vu$C[IL9d]5XLPabEaEj0MQ- %SEet&i'$=qE2$9onCJht=UD!1G9W56J!W$6PTRVD6.Rhep0tLu>6.hSU=CY4Af3+bD09LOkk`YPH)eR1/bZDtr9dF)(;KRDYZn6e %VEG/1f4oX@.]qCHU8BI-DZ,IK_P6dtGcA,+W3[7t<1TF[3(L5Xpr937m&5/F):VOML0%)2#.<:-=$0-'H^0+ep_CD(1S04Sop_gc %KjEb&gO8Q0[-'5YK?6+X[GT%!]Y!;dB_ZmJ3qYgXb&=.=)if8i8#n&BB`\;1V:X^$qLRKb=<"c`8$WK12cgO\i;c$$-?nnjMs8/? %:H>/\i0$r80o&'fb8npcEpN4&%lZ\oBu%0:o$33ZT1aOF*T"aZQ[T\JO(rk+\afr>jrH$0pN_kaFf@=A\UcScVTS8lP5e6so46ei %UT;S;L*UA[Spc#C09PkZf/Eq!c+6/rB;thMkqhcG8_D?eqtp>3_<$ArC(&XEn79di#/5W52q.Z%C:_1@@HObj %F,L-6(2fPjF90^C=g4@?/LTbDQR,V[\^f.,Z1?;?Ra*K$n%-tsTkZUr=q$gA4+D(OC-&i,Hqt%D;`3Cg/FpI(FDgD$R]Th(24[t> %h\,B2WLD,7Q7gP@T"1lcgiDf9%I>,EoTs;R2sQR<"d`CekIi@Vb\B2J=uuE,jqk"oF+Q5kZLLhml.he-[nQ7"eT>^$S%`H""9hA*LnN:Dg7D#S01[q-9BRu@;M:$:(.h%?p9C-&h-3kA+$RFQCsX!MpbBc5HCZ_H(5<7CZHN%D#u %DO,]R:,SR]1(8)KC"7qBr%SJ*8Un)D[feTlHW_=0;Q %Am6XS4R0k'`\0+VGYf/p'I^Il4aR9B#AIf7\p^KihsGIXKrMh<"SN"LRS01L5k1+04R+`0fH!5dm@d*aSrK5^RuJOVnmg5+=N` %f,)`88di(a%'_#^ioGVKCrN7RAZWiA1NY6^6[>d-?u#\EKjE9c:]RFJ,`23lWhZbmfOrW^?T2PcqZTu7Oll?,J@rHuf+D#/i?(RuWq/Sja %N;Hq0pJ?(3QZTLWAI#VM,jr'qH>;Wah^VQ"QZn)@kq[024S:@<#V,`-iER1!HWNBX(Nq/s0>>%ZkNQXL;Z^VsMr%K/0;WaFP;q_o %4:VC[?-"_G$8;0\dp`T"ZO7Y&ADe9=iJuJjHJ`^$[hu^5E;.D"X67.ScDU5Q&MZ--$WGb-$hk=-Sg`5cH&L5ekr7]U/;CktgtD"V %!n<#'l%V:7qd/fQ4(hu=^l9+iJD.^5BdnaAIPi?k(=odl6#'gq_$Xu2eV.m42_,sTreGCqX*jP!/8),,Y"1d,a_!QZLcAU2@I9Im %UQ]mQ2S1("F5`WX9H&t;f=+OmY*nmm4C`#j;8tH+\H[tg:AkW(OM$m&7X*37VV*7UkAE^^VA0J<`akS"_i3ZIfp,#CmkUbRr[#@' %_&6[n-C)s2HN:#RE!b.,>O;@0\FOMoiEstW/l9&WO1EFAgn[)g$0IBd%bG]D4TD'^>KIp[*3p2KEJbRicW:]`& %*l^i7RL1dXZl7POZ00M6F8IYVN-BTr1HF]F\):Q]Z]dN4o>3>0Z`B[1f=1lQ1H<8,$g1UOC-"`dEUV(n4H0R4nS#l>Y%o>0]BTRN %p3!U"n)^Yg:-N95Z*:DuWr"Q!>?s1D\)@<_qdh9P)i`Ola=*+:3PF1k'ak5E,k,d %c.s?)3@MstrFu;MA$486#.o6VkV[&2miJq.M(Np[YD=.$]aRR0Zk2pN1gI[bGHBf2c`F=7 %ep_LPk6Eei'ON]2e'')'aBY&O:8a\GM1$#cC#BIF"Wc7f5A$M %k=J/LP]r^D5*/m=>;J*\VYA*aeWnoTQ53F&=2f8`>RdQuPeUK4U[-N(B %;GPCf24md^=]ZNfU7\^]riV2l(?u$7L/EK5dXl[$o+mmrl<:sJB#Q7k?u0F,:[gq:<\>3+fZa57k/!E\6/#;KYcDt=1%s3K^nK6#-IO/dkVZ#-@n7"[Y_p@phFN#dbHE %O&^_u+ALGf>1P3"h.O-S9DO1raL9`tI-+]5S!W\+ZO6`'9DSL(A6[W]Hrr0[_a.GBV0nuXZrad89DP)\\GsjNI%L'W0D/5W!;BPI %F=Eh>X+3GE4QX%C;)G=1f]Q;ML!PM%me'ekOt51uIR286>5V\kF)"?-)p7bY^Ua%erV9ba#L/TS2O)t0IffMp\MEtaT$(T %^YJ-6S!01YYFkj?&3Y*Bke2GZQ!BGS3MiAL^Ak&?13.=r24/A^[gjfqH7gNN#P%;n+H:Ed.@gu^YS379d]2.IXeQ)%!_T' %f3-IM]%>:.j=edD>PMMh5=9XDJtjmW?9eIsn2r'pq;(B"+6pH)K)Ws,IT+c:[Ti\G\rSK[<.no>`u"MW5Q=sdQ?43Ub.j9>d!gRR %RGbBDii#EHo=]V%Y,:km5KiF&$f1.3J#f47bc\M";`XrE=X7Oc>moHRkC9P)_9)P.lTa7lkJ-!0X@QX`?9b36bB;,(F0>LkYFe#\ %OiNc-YFkisI`o9_Dq=2md/3SR42o+MO)OR"#Obmqk,[Y6^=U\\M:d6cmJQ_Tq-VuFp093.?9\r>Y2/BPGZEIV_J"NdD'a1&q9dE5 %rVY9:D0KtPE3GlCgJ^Tns7&:e3B(YshT*+p@62tDr>*,.02O2_j7J)jHi<*8V'Xp_VjC#dhs*.Ee.qhIYQj&^")ST]*Fo$qY>,ajT^eMn+H9r$q^*&KRDneE#3CnO9bTqEAG)[C7\cHV3uX)J[HqRS4kq#OfWX^VEi6jq;0`6aK&^4.$hkT7^\4-%c$f8afY+hC%OX.Y %kD/BGk!qFPGgb7#G^5@OY,^1Rf\4AUA4KHT%NaKPX'5nDdPkZW['Nu".0\Q*8,:QN+]j'_n.]QPeg@-)-*)mAa09BMN<.jeK8$Y)oj&QA#L%=`Fm*.BX(>hheJRJBmm(-ptZ4r\+YMP,b3.L]3',Y%AukS4oE2>L6G-.2-P!hr".T%/+%<8B+63@qb]1nY"ql2F%K?! %lYN<4DH:(j=V`B,=57VI7iG[u2/Z3@h^@;tlM7sj^UcWTU1^e#Wu:Ic^TN%b1/'6_-%DXQN+p&`"pt(!)5fE95"0saph*M%1D`^E %T4sN^da/c:/jKI8efN^u<$j-`0W!*(HX(Z/P@0m7a#p$T.$:U.,*R>S\[01;4=;r;Q6HTD+4oVETp%d[ %;I/p^cEm:DQ<\=K5&Tg3_2_XbS"ip1/JapqXl7>m/3>2eEh/,d"f+F3D%=_-[u6_8asQOTlMM]i5;LQAdc'4b]@tsFT9t06UYjU( %Z(#c(18<"3S+SA]UK`6!o>ZFWGgt"X4dO(E_t?=Uk#-IWSP7UACR=ue#%tn%CYeS/dc-kb*PF%>e@<$MFiNhTQDmrpj[Ym=cdDrI %>kP%IC]7sL)WJRdkkj#JVJeY1XWgECpH$-5RWJ)O]S)(ugUae7jlK\4c^\DoN %ek/YNX),LL=4^2rLu@P],3oR`;,-%C8sHQR5(g`rFko@`:o-F#Fl&.XSA23JDA[CXejVA^rF?PZ^n3r`/8IKb=N!FF8JZ+eWf1Q4 %+N--bd7*%O1YR*j\F1\1;APaD!JXL<-Pg+bd7EO\kkO!>!S_;ISsC"Z2.s`^?D\fHG#@>NgNQE^RiV-gmn^Ue_^XNmpodsKG%U2a`5kSEJ7-C-2+_=9"bRY %pCeS$,AYkdA:*a01k\[#146SVA7%d9^tir&HS01WHH0mMOit)LaNjC$W=P1WWV)[.jJt<[jWA@5$p:31BWFR32Y&V)kr]6Kf14Qa %:>n@Cqm;:YLpN#]_r2-Y>\-7jN8D)*FtKitBaa)W4uLO.NDFDh/tf<\/e1GX0GiGs3353Ri-2?J/l$'rRZ@e8+UjS`a^8]tUKm`' %/>I3G!N/+;-n95=XnS"b7C:Y?eKhG`B^gE,`WCBr29pJfT4=(n]8h4\3QXu`&NYUYC9MRc&7i! %d+,*_)K^#J@i".cpqGLRa[@M?RjX%o6r(,9S0.7'[LTF"0tA`o:8l6<-5>,?&"V=]fqClb9YW%2!&%ofbtI&2`'Mm):^?:(#)om;9p)9!SX4rVT9!0.PHGULuE2c&kR>tu^:EGIg^?fdXdDeU4O?2JJ %\"ck-g)T(T;."%ajlSM2CVfT8BtJ6!A,eTeKl@4tBo:$J;u)%$Z-L>FGMN1?>RT>H5A=`_ps[f<*9-9de+0Ck'\s?5G74Y0\'hS[ %Bq&,>5-'>WY(Rgu"G+aJZ%O.'"GMf11*@FVC9E3>'BC^a./e:18qT-[g$0FC?A;DK+p>8T"eVGo)h=]P$e6Kcb?(A&CY/<)>#o=o\QhKI8*u]/Vg8cdZ@!=O)dd-iIFihhi=!NVb;)l5f[YD1Zk_Zap\Y%c2"?I@Y %H'^1I2*FS7m(CS<"MWCQF'+r"gpem=cC3n%Ni_Ul+HEJ00KajT6/4aBkJtNsL>ft>)WmMW)[Fg=@(i4!Gf_nPbS=JcGX^KXDV3&.1cLGt %=,p2:>=MSN(0RGX,5Z\2eYHiUGGk>P5^,Gbd]o03)H8kp(h;Rk$H!p_[n&EQ>.oLlnt95enGr3cm7W4Ua76GA!!fORpcF7>F(pf4nV!/OlsX'Fg\qjh4ai]m*48Vl-cP-Eda;`A@+ZsX_9G'^%A4P>'/6>PQ-&Eu"-]HIX]E<#9 %%'JufCU7c_in>$?=O4SI.fif&;[;iPOCaaa8;RmFQQ2AT(6M4;"@iLq#7)s^>(5$\pqkUPEXcn343r? %?6-AmTal;&&oBZEd\ZS]\Wsn4&*5U=l+8N*jW@*on,;'O9-"h5k13\45.hT@[F+Xn;n]8>FR&["rfJH]VO-;rWjh.^-Bu$>:Zu5Y %kM]D7[YDSiL"EBJ4h@?AGcYO&S@\$q/?bjBHkSZRLrGu19>uP@U-`*[;mDdk$J;,_rcq5*$fpG:U_9K8HYHbpYK%FI%qHetr/+?E %#f;ePXK3a0.Era)@f'-HA7uHNs"J5#./E8uG?JR)+_Iu[G%n/tV:od(97Kd62?O@!0h]p]G!UUgcSh4!XO+DWEEJ!7jG4Hj[uLm6 %@H%d+YaT&\lD?k[--,=:>MY'?V+rlYJZpqA;]3+j+O+3bMDF%79 %17D'Dcbq[oj'md?124/%(C(gp'Z0:-KA60"j[H0kPWtBi`PRVaa[,ZaFQVA]Wp_Wq*fmY)pc/,V*E*Waa&Bu%OJhnZV0';RH!biZ %>Ml8Pl0F96&m)e>g_0$D\+&qc=nVTCL?QtW/u`[;S<8m=C&3aoL?DI)7C!@6M9 %As@^_fN%g&?H7.TrJIFp[BML0L5RemVA:J),ieAD\/kWGIk_:EA2\[j?`=9Kt'&5pdBJFm% %bpnNqMWAFVQ8%qjs38p0K@a'T8Q,1+:iP1g%(+`,;;O#++X&"f,*/UK<['BYY+!P2/^;a;SWZr].q;M?`Q(n;Ea1TZ'%C##B/]i'()E)G8%=g)!p!nRTQdk_lLbH#g %p#Bi7O[=\0AEngN%;M%52W,o"=H*k.hLqP'^BiB/rd&"scA8tkS.*p-.8,3sg$!(4mO+90&5C`9]mB#KQm>-lX>X%Q=Z2%%/H&\oUq8KK(W9epMp?W8Y0q9#`Zl^/;MPWKrZ-qjakuLtDoO9/Is'fKVWb?QQP_nRT.o&1`,_dUpOqc'hL]jsYL\7`WnenLE %N4p.>XB+-Q5lL'f&!GKKm3I\k$-$._lQ^b\C3f;SGr?^'N,aI'@8#?hm(nKi0s7lGH5?@sUC>Q6Cid;2:cG>@Xs7lOCK[5.J+M"d %#<2ZBdRD>N(4gDgRk@l>ZH2,5G?_Xl3Q\!l`'7Q"k@>0D0;aBiC0uC).OZ!f5g.:-GOg_HLj.ssoBTJip[;K(@TVdn)#,3P/#t0O %VlXj3#_.Z_g3s=Hg:c[cBSDGL[(eqi]523R>CCqtI3!e07fTXPYj$P=IC`?_afWp6n)3$HPo)d(gqhb7.$",$4+QfQ`2o3]^[qJY %(i<[Uj'VRk(Oj"_dskDOQ+`H`)ePq-mi@23,R_Vt@YRl_DWN[MaJ*GKh%%Etj"#tJW2LS/&g^2bm*fcE.u_P[6s_]7R)&_7',]a0 %raR^`b_^q/5=A)*GQ]Rm;"/cSSmsQ=a7(U\_Ij]gOe?WajYIMo")*RR;'f@Ji>EMfi+-Lu1GZkhd%Y,?JHp-o,pTCJ\l&ik]Ta!f %!0=R..R4,eAS;a@iH^_p_3\[u!9,D)7V*[_2t@RF*_!/e7m4GG*]SeEC#Cm0+2-HgAT'+;%C %1:6Q?"(5OP3e1;#m+GQB,lJ4PK>"n3oBE>2Ek2A)k.,&e/+9HjI4p%JLF9gXdc-<+#S?tSNQfa'?uiP_#]J4P=6n/V'1+9P@5 %%&Yd-$9Z\*j%(+ZWQ>O`Ck,q2&%GRO"__=ePURJ>?proo?Jkg1-ufMAYQsu!:f&Jb^aI%Aj?&a!6:es:iUJufUI[@[QmsJ`4M2uX %6bkak0T(hL!R&Qs6<[o&f5k.\]1_ %!tf!E<>-3o@g)m0!HKAr]Y\(bE1AHd<:E;C3?:m>0RsFK/BjZH%sSd"/7rEm`>/GYA/2ES^4S=o7CKoVJD;8H.OYLdj&Z/5[h*(< %YmMt7Om$#N^p@Xr5GTruja#$R,#JsE/OC$j`02Q6@HS%f'jsQH#m?n:3J($Jq$i$"(f`j-O>Ntr=Q"]d4CM%ePnL">R/r_r(-n`` %'o>>P&ql31e0:4[`eKh))&Pm'L`QTb;R(Qi\:YU^"F1`H)Y0fC.k56F!57#"n?F/K"@ARdN/9-L5j#ss<7G1%]`&ao+>P;p*(S(B %9EB)nI#6;V\6)QVpkfE+9XFiDK3J2.I)_!o;R\Y_d5UfU*Z:K;%[##b@%+J[: %b#9Rl$:,bq:fKC]V]t_cVNQJ,)*m+Z'N:53L3CK$G$Aq@fn5Q+u'K70G!sfCb8:*?:F_q07iDN %Y]#m/LR&_T?NL?I%6-<1=lgpP42?t0W])',J(DNfSqK!u*>24% %MEo*P#/)<[IEm_=0QIRPP84]4<[XD23#-;,6m\Df4)@_^OY@qdQ0Kbti@3aP%/tfO:W+''8k+VJFI%0Y^^:*BCBI>X!;[s-3`$mu %(.\qQ'"\Ej:fp%4(!3F8+Hd."$X+gN-ldY.'nQ&Y*:f4ahkAUf7Ec#mm@6[l;1Y?"$%W.-M"$_G!7D&C.hEsI#kSrH(n``2:t7+s %5ZjZiH6:X,&]+/J$j[`O;T0iT=iSbf-5MRSYa>KZ>7jsk*s.!":oo0s`"iBpB"#L!/FdC5qci!aaJ=M[;7*\1CN7"cIAaIRkSu9% %[]gsl0@C&t&f>.%R50@B0k]Sr#3q:bF8u %6tjV\4Db[1_?FV.#le#@j#--'D1[F%'"Ndo6H'$[YF$jF4K5Q<'*/j+U=(`55$60k@fUkOU@YFpuP3g:oTH/a%@*[HG_/u#\g %UR\PV,GVH&E"d1:W\Qk'&]XtKLhEZl"eUi#DfLB/0dae@5D(>`/81Z,"%bX\$'Zft`[MO#IGhj"B/!O"nV0.+C7dbJL.r4Q/jL*V %aL.m5:!"EE+E3BMW[P8?4C0/Y.'V&)"9h0qJOW',_,*ED0/3fltTiV@>$_0bu)g*EYPSH.a3J/UdL!g"G_@_W'#Sc4Y %ZK*fN>ES25n0ir1+CubI8/sAhIKn6=ZW,`\1C=71M,C7a"("$,D#qf`lA17Jd0=-C=De<$(,Sr=M%"uq*]Pl,=pkh\6P$9c/OB+f %5U8T:ONGU"BbAa)PL%#j(.HWH.(0C:6NrbVk-VT/7\noZD,elU"e60j`[3GP'Kd9VYpu4p'U]jF``k!:36W/RJ=mO5B2L4q!>7c1 %N;,F8L5?nd'/Bg/0,cWu-raB'FsNA!5_4NL,h,>W:..s#`PKC?Ld9W'>]<;U:d2fKU04u1ZDbnL %/bXct#tuh*ZdIugqLTL0^Dp#aPX%YQ=W5#L&K:1KVj[Hi@/\Q9WWc:2LC0n'dLOm;6Y?2k=Su>PfJ.B.=C+U^\_QX;X6,*M!k-Q7%1Hd8n?RuWm8>Im^O,>1e %!ZfOLQjXm;=UWbNA14/N6^8",1Fc6f&DWpU_\NmUP'J2@*_C%]&cDp_PrY-T+Vt:8<9'o*MV'*sUOi:'0e/ikW<<99;]%2okYP3" %,E#27Fa6hm)(j>sB3:J+^'2/%dQiFq!WFCJU;3fd:W&i %3jqVqffWq@'t#nY&0e.Y@!3UC__(B7'OjHI#up@@BiA1,-4hY,MmuX %pIcL$a*3Cb;XMf)!$b=u]$LQf"VZ;E1iYtmNO_O<51%#.1+T)$5u&'*TuQ@X*aHJC("6Yf&7_GVS=a/5$CO/ZQT_ %N?D\"MBg84i)ptcOa)h`(."-S0^^d1!ff!+a!3?N%%92-:l6VQ4#A@aP(3a,Lj;S;9"!&DLYels2Pl=#P0BYK0o6GLilq'T%D^12[F;+H(]EfZnA %9^[E1^WeU1GKu&4K1@OkJJ0af!Wmou@H%j7A2#elNN$JkR_",k!=_9D3 %U(UTVj+D!JdP.)OBaZs*2#?6CNnR5@:LQp*WgST//>g6;N5V5;;.fr%]OFQ.dK^UrT`YP:6mk!&BrKKNAN.$7%OMq3.>`XeicbH(dNgJ!@l=bo0h%ojJ1K36#-iWtBa,X?LFaXB`E!hEb0,Z?&:p^gAH(pu[i:%MpaaADp`T%[!c4,1:OL$F)S@ED/MXX/rU-/3&foaJ2m)De(?RQLnliH5_e:3]$c8k9HjcQ>fcaenWKW@a+;eBdsiY4O_#G.8*@KWNI<;@-R_!jlje\^ZE*e_J# %Op3D(%`Y96/5TW-$WE*s1f\$n).Fuq&j@L2DCPm;"%XM("$!t_^b?&H)+$-I/@U^g/;@7Det\.:ZtR:bME)7>/RJ/Q_;g[bbeQl' %5QaQ;B*BlgANAVC-H<8FY=YV0U@_Pl87i]'1YQpga4Q_jfmkDk0H&irrhbg^2SA_f0!q!ai69$^AaR&3+Q]uOR(/b*9e*/:eYJiL %UiMo^MNWMt"2Da<2t=g?pWCm.QK'qV1h'uq_``j80EigQ=tYCSE@J&pdC3XkgQJM+`MFW,'lhKR>#gi]BOpWVi_d^WK#G!oKeuk% %,'cIR\\qB2pn;H%%i,7+lG.ol/Zh^Q2MT&@)So$cBU,4q"XFP%68N'F'5\RM,\B[Q\/!hB+Ajdf!]2L:-Xa)Ro,ef8>>%p]I=728 %L(e9U>6g"A\Z:GQRbF-WWnh<.I3XDQD:g#/CFF@Ef8pINfJqIG@L3ZX)G%XZNScD^L60c5V9a1Zs,/%r-iiG\1/n-r/oSk"G'mr1*c %)8?U[K.ZSLrd#hf4/dr6+-h0rZ2~> %AI9_PrivateDataEnd yaws-2.0.2/www/motivation.yaws0000664000175000017500000000102212605311413013332 00000000000000 out(A) -> yaws_api:ssi(A#arg.docroot, ["/HEAD", "/TOPTAB"]).

    Motivation

    I wrote Yaws for the simple reason that I needed to build a website for the first time in my life and I didn't realize the amount of horrible ad-hockery which currently needs to be applied in order to build a website. In particular, I thought that php was designed in such a horrible way that I simply refused to use it. out(A) -> yaws_api:ssi(A#arg.docroot, ["/END"]). yaws-2.0.2/www/jsolait/0000775000175000017500000000000012605311413011766 500000000000000yaws-2.0.2/www/jsolait/jsolait.js0000664000175000017500000003417412605311413013722 00000000000000 Class=function(name,base1,classScope){ var args=[]; for(var i=0;i0)&&(typeof args[0]=='string')){ name=args.shift(); }else{ name="anonymous"+classID; } var bases=args; var __class__={__isArray__:false, __name__:name, __bases__:bases, __id__:'@'+classID, __hash__:function(){ return this.__id__; }, __str__:function(){ return "[class %s]".format(this.__name__); } }; var baseProtos=[]; var proto; if(bases.length==0){ proto={}; proto.__str__=function(){ return "[%s %s]".format(this.__class__.prototype.__call__===undefined?'object':'callable',this.__class__.__name__); }; __class__.__bases__=[Object]; }else{ var baseProto; for(var i=0;ibaseProtos.length){ var privId='__priv__'+__class__.__id__; classScope.apply(this,[proto,privId].concat(baseProtos)); }else{ classScope.apply(this,[proto].concat(baseProtos)); } proto.toString=proto.__str__; if(proto.__call__){ var NewClass=function(calledBy){ if(calledBy!==Class){ var rslt=function(){ return rslt.__call__.apply(rslt,arguments); }; var proto=arguments.callee.prototype; for(var n in proto){ rslt[n]=proto[n]; } rslt.constructor=proto.__class__; rslt.toString=proto.__str__; if(rslt.__init__){ rslt.__init__.apply(rslt,arguments); } return rslt; } }; }else if(__class__.__isArray__){ var NewClass=function(calledBy){ if(calledBy!==Class){ rslt=[]; var proto=arguments.callee.prototype; for(var n in proto){ rslt[n]=proto[n]; } rslt.constructor=proto.__class__; rslt.toString=proto.__str__; if(rslt.__init__){ rslt.__init__.apply(rslt,arguments); }else{ if(arguments.length==1){ rslt.length=arguments[0]; }else{ for(var i=0;i1){ if(mod.knownModuleURIs[name[0]]!=undefined){ var uri=mod.knownModuleURIs[name[0]].format(mod); searchURIs.push("%s/%s.js".format(uri,name.slice(1).join('/'))); } searchURIs.push("%s/%s.js".format(mod.packagesURI.format(mod),name.join('/'))); } for(var i=0;i=arguments.length){ throw new mod.Exception("Not enough arguments for format string."); }else{ obj=arguments[cnt]; cnt++; } if(obj===null){ obj="null"; }else if(obj===undefined){ obj="undefined"; } s=obj.toString(); }else if(s.slice(0,1)=="%"){ frmt=new FormatSpecifier(s); if(frmt.key){ if((typeof arguments[0])=="object"&&arguments.length==1){ obj=arguments[0][frmt.key]; }else{ throw new mod.Exception("Object or associative array expected as formating value."); } }else{ if(cnt>=arguments.length){ throw new mod.Exception("Not enough arguments for format string."); }else{ obj=arguments[cnt]; cnt++; } } if(frmt.type=="s"){ if(obj===null){ obj="null"; }else if(obj===undefined){ obj="undefined"; } s=pad(obj.toString(),frmt.paddingFlag,frmt.minLength); }else if(frmt.type=="c"){ if(frmt.paddingFlag=="0"){ frmt.paddingFlag=" "; } if(typeof obj=="number"){ s=pad(String.fromCharCode(obj),frmt.paddingFlag,frmt.minLength); }else if(typeof obj=="string"){ if(obj.length==1){ s=pad(obj,frmt.paddingFlag,frmt.minLength); }else{ throw new mod.Exception("Character of length 1 required."); } }else{ throw new mod.Exception("Character or Byte required."); } }else if(typeof obj=="number"){ if(obj<0){ obj=-obj; sign="-"; }else if(frmt.signed){ sign="+"; }else{ sign=""; } switch(frmt.type){ case "f": case "F": if(frmt.percision>-1){ s=obj.toFixed(frmt.percision).toString(); }else{ s=obj.toString(); } break; case "E": case "e": if(frmt.percision>-1){ s=obj.toExponential(frmt.percision); }else{ s=obj.toExponential(); } s=s.replace("e",frmt.type); break; case "b": s=obj.toString(2); s=pad(s,"0",frmt.percision); break; case "o": s=obj.toString(8); s=pad(s,"0",frmt.percision); break; case "x": s=obj.toString(16).toLowerCase(); s=pad(s,"0",frmt.percision); break; case "X": s=obj.toString(16).toUpperCase(); s=pad(s,"0",frmt.percision); break; default: s=parseInt(obj).toString(); s=pad(s,"0",frmt.percision); break; } if(frmt.paddingFlag=="0"){ s=pad(s,"0",frmt.minLength-sign.length); } s=sign+s; s=pad(s,frmt.paddingFlag,frmt.minLength); }else{ throw new mod.Exception("Number required."); } } rslt+=s; } return rslt; }; String.prototype.pad=function(flag,len){ if(flag=="-"){ var c=" "; }else{ var c=''+flag; } var s=c.mul(len-this.length); if(flag=="-"){ s=this+s; }else{ s+=this; } return s; }; String.prototype.indent=function(indent){ var out=[]; var s=this.split('\n'); for(var i=0;i0)&&(!this.isWaitingForResponse)){ var data=this.queue.join(""); this.queue=[]; this.sendAndWaitResponse(data);} if((!this.isWaitingForServer)&&(!this.isWaitingForResponse)){ this.waitForServer(); } }; }); mod.RPCMethod=Class(function(publ,supr){ publ.__init__=function(name,proxy){ this.name=name; this.proxy=proxy; }; publ.__call__=function(){ var args=new Array(); for(var i=0;i out(A) -> {ssi, "TAB.inc", "%%",[{"websockets", "choosen"}]}.

    WebSockets in Yaws

    WebSockets! The new kid in town! Joe loves it, maybe you should too?

    WebSockets allow for *real* two-way communication between the browser and Yaws without the overhead and latency that come with polling/long-polling solutions. That should be enough for an introduction. Now... how to use it?

    A simple example

    First of all, here is a simple example. It shows how to upgrade connections from HTTP to WebSocket.

    
    out(A) ->
        {ssi, "websockets_example_endpoint.yaws",[],[]}.
    
    

    The above code can be executed Here.

    Establish a WebSocket connection

    To establish a WebSocket connection, a client must send a valid HTTP Upgrade request. Then, from the server side, the Yaws script (or the appmod or whatever) should return:

    {websocket, CallbackMod, Options}
    

    where CallbackMod is an atom identifying the WebSocket callback module, and Options is a (possibly empty) list (see below for details).

    From here, Yaws spawns an Erlang process to manage the WebSocket connection. Once the handshake response is returned by Yaws, the connection is established and the handling process is ready to send or receive data. If something goes wrong during this step, Yaws returns an HTTP error (400, 403 or 500 depending of the error type).

    Supported Options

    The following options are available:

    • {callback, CallbackType}

      Specify the type of the callback module. CallbackType can be either of the following:

      • basic - Same as {basic, []}. This is the default.
      • {basic, InitialState} - Indicate your callback module is a basic callback module. InitialState is the callback's initial state for handling this client.
      • {advanced, InitialState} - Same as above but for an advanced callback module.

    • {origin, Origin}

      Specify the Origin URL from which messages will be accepted. This is useful for protecting against cross-site attack. The option defaults to any, meaning calls will be accepted from any origin.

    • {keepalive, KeepAliveBoolean}

      If true, Yaws will automatically send a ping message every keepAliveTimeout milliseconds. By default keepalive pings are disabled.

    • {keepalive_timeout, keepAliveTimeout}

      Specify the interval in milliseconds to send keepalive pings, by default 30000. Ignored if KeepAliveBoolean is false.

    • {keepalive_grace_period, KeepAliveGracePeriod}

      Specify the amount of time, in milliseconds, to wait after sending a keepalive ping. If no message is received within KeepAliveGracePeriod milliseconds, a timeout will occur. Depending on the DropBoolean value, a close frame is sent with the status code 1006 (if DropBoolean is true) or the callback module is notified (see Module:handle_info/2 below).
      By default, KeepAliveGracePeriod is set to 2000. Ignored if KeepAliveBoolean is false.

    • {drop_on_timeout, DropBoolean}

      If true, a close frame is sent with the status code 1006 when a timeout occurs after a keepalive ping has been sent (see KeepAliveGracePeriod). Disabled by default. Ignored if KeepAliveBoolean is false.

    • {close_timeout, CloseTimeout}

      After sending a close frame to a client, Yaws will wait for the client acknowledgement for CloseTimeout milliseconds. Then it will close the underlying TCP connection. By default CloseTimeout is set to 5000.

    • {close_if_unmasked, CloseUnmaskedBoolean}

      If true, Yaws will reject any unmasked incoming frame by sending a close frame with the status code 1002. Disabled by default.
      Note: According to RFC 6455, a client must mask all frames that it sends to the server (See RFC 6455 - Section 5.1).

    • {max_frame_size, MaxFrameSize}

      Specify the maximum allowed size, in bytes, for received frames. By default 16MB. It is also the maximum size for unfragmented messages.
      This limit is checked for all types of callback module.

    • {max_message_size, MaxMsgSize}

      Specify the maximum allowed message size in bytes, by default 16MB.
      This limit is checked only for basic callback modules.

    • {auto_fragment_message, AutoFragBoolean}

      If true, outgoing messages will be automatically fragmented if their payload exceeds OutFragSize bytes. This flag is set to false by default.

    • {auto_fragment_threshold, OutFragSize}

      Specify the maximum payload size of each fragment if AutoFragBoolean is true. OutFragSize is set to 1MB by default. Ignored is AutoFragBoolean is false.

    WebSocket callback modules

    All frames received on a WebSocket connection are passed to the callback modules specified during the connection establishment by calling Module:handle_message/1 or Module:handle_message/2, depending on whether it’s a basic or an advanced callback module.

    Basic callback modules

    When a basic callback module is used, the messages defragmentation is handled by Yaws. From the callback module point of view, all incoming messages are unfragmented. This implies that fragmented frames will be accumulated, thus basic callback modules does not support data streaming.

    A basic callback module MUST define the stateless function Module:handle_message/1:

    Module:handle_message(Message) -> Result
        Message :: {Type, Data} | {close, Status, Reason}
        Result  :: noreply | {reply, Reply} | {close, CloseReason}
          Type        :: text | binary
          Data        :: binary()
          Reply       :: {Type, Data} | #ws_frame{} |
                         [{Type, Data}] | [#ws_frame{}]
          CloseReason :: Status | {Status, Reason}
          Status      :: integer() %% RFC 6455 Status Code
          Reason      :: binary()
    

    This function is called when a message is received. {text, Data} (or {binary, Data}) is the unfragmented text (or binary) message. When the client closes the connection, the callback module is notified with the message {close, Status, Reason}, where Status is the numerical status code sent by the client or the value 1000 (see RFC 6455 - Section 7.4.1) if the client sent no status code. For an abnormal client closure, the status code is 1006 (as specified by RFC 6455 - Section 7.1.5). Reason is a binary containing any text the client sent to indicate the reason for closing the socket; this binary may be empty.

    If the function returns {reply, Reply}, Reply is sent to the client. It is possible to send one or more unfragmentated messages by returning {Type, Data} or [{Type, Data}]. It is also possible to send one or more frames using the #ws_frame{} record instead, defined in include/yaws_api.hrl (useful to fragment messages by hand).

    If the function returns noreply, nothing happens.

    If the function returns {close, CloseReason}, the handling process closes the connection sending a close control frame to the client. CloseReason is used to set the status code and the (optional) close reason of the close control frame. Then the handling process terminates calling Module:terminate(CloseReason, State) (if defined, see below).

    Because just handling messages is not enough for real applications, a basic callback module can define optional functions, mainly to manage a callback state. It can define one, some or all of the following functions:

    Module:init(Args) -> Result
        Args   :: [ReqArg, InitialState]
        Result :: {ok, State} | {ok, State, Timeout} | {error, Reason}
          ReqArg       :: #arg{}
          InitialState :: term()
          State        :: term()
          Timeout      :: integer() >= 0 | infinity
          Reason       :: term()
    

    If defined, this function is called to initialize the internal state of the callback module.

    ReqArg is the #arg{} record supplied to the out/1 function and InitialState is the term associated to the CallbackType described above.

    If an integer timeout value is provided, it will overload the next keepalive timeout (see keepalive_timeout option above). The atom infinity can be used to wait indefinitely. If no value is specified, the default keepalive timeout is used.

    If something goes wrong during initialization, the function should return {error, Reason}, where Reason is any term.

    Module:handle_open(WSState, State) -> Result
        WSState :: #ws_state{}
        State   :: term()
        Result  :: {ok, NewState} {error, Reason}
          NewState :: term()
          Reason   :: term()
    

    If defined, this function is called when the connection is upgraded from HTTP to WebSocket.

    WSState is the state of the WebSocket connection. It can be used to send messages to the client using yaws_api:websocket_send(WSState, Message).

    State is the internal state of the callback module.

    If the function returns {ok, NewState}, the handling process will continue executing with the possibly updated internal state NewState.

    If the function returns {error, Reason}, the handling process closes the connection and terminates calling Module:terminate({error, Reason}, State) (if defined, see below).

    Module:handle_message(Message, State) -> Result
        Message :: see Module:handle_message/1
        State   :: term()
        Result  :: {noreply, NewState} | {noreply, NewState, Timeout} |
                   {reply, Reply} | {reply, Reply, NewState} |
                   {reply, Reply, NewState, Timeout} |
                   {close, CloseReason, NewState} |
                   {close, CloseReason, Reply, NewState}
          NewState    :: term()
          Timeout     :: integer() >= 0 | infinity
          Reply       :: see Module:handle_message/1
          CloseReason :: see Module:handle_message/1
    

    If defined, this function is called in place of Module:handle_message/1. The main difference with the previous version is that this one handles the internal state of the callback module.

    State is internal state of the callback module.

    See Module:handle_message/1 for a description of the other arguments and possible return values.

    Module:handle_info(Info, State) -> Result
        Info   :: timeout | term()
        State  :: term()
        Result :: {noreply, NewState} | {noreply, NewState, Timeout} |
                  {reply, Reply} | {reply, Reply, NewState} |
                  {reply, Reply, NewState, Timeout} |
                  {close, CloseReason, NewState} |
                  {close, CloseReason, Reply, NewState}
          NewState    :: term()
          Timeout     :: integer() >= 0 | infinity
          Reply       :: see Module:handle_message/1
          CloseReason :: see Module:handle_message/1
    

    If defined, this function is called when a timeout occurs (see drop_on_timeout option above) or when the handling process receives any unknown message.

    Info is either the atom timeout, if a timeout has occurred, or the received message.

    See Module:handle_message/1 for a description of the other arguments and possible return values.

    Module:terminate(Reason, State) -> ok
        Reason :: Status | {Status, Text} | {error, Error}
        State  :: term()
          Status :: integer() %% RFC 6455 status code
          Text   :: binary()
          Error  :: term()
    

    If defined, this function is called when the handling process is about to terminate. it should be the opposite of Module:init/1 and do any necessary cleaning up.

    Reason is a term denoting the stop reason and State is the internal state of the callback module.

    Advanced callback modules

    Advanced callback modules should be used when automatic messages defragmentation done by Yaws is not desirable or acceptable. One could be used for example to handle data streaming over WebSockets. So, such modules should be prepared to handle frames directly (fragmented or not).

    Unlike basic callback modules, Advanced ones MUST manage an internal state. So it MUST define the stateful function Module:handle_message/2 :

    Module:handle_message(Frame, State) -> Result
        Frame   :: #ws_frame_info{} | {fail_connection, Status, Reason}
        State   :: term()
        Result  :: {noreply, NewState} | {noreply, NewState, Timeout} |
                   {reply, Reply} | {reply, Reply, NewState} |
                   {reply, Reply, NewState, Timeout} |
                   {close, CloseReason, NewState} |
                   {close, CloseReason, Reply, NewState}
          Status      :: integer() %% RFC 6455 status code
          Reason      :: binary()
          NewState    :: term()
          Timeout     :: integer() >= 0 | infinity
          Reply       :: see Module:handle_message/1
          CloseReason :: see Module:handle_message/1
    

    This function is called when a frame is received. The #ws_frame_info{} record, defined in include/yaws_api.hrl, provides all details about this frame. State it the internal state of the callback module.

    If an error occurs during the frame parsing, the term {fail_connection, Status, Reason} is passed, where Status is the numerical status code corresponding to the error (see RFC 6455 - Section 7.4.1) and Reason the binary containing optional information about it.

    This function returns the same values as specified for the basic callback module's Module:handle_message/2. See above for details.

    Advanced callback modules can also define the same optional functions as basic callback modules (except Module:handle_messages/2 which is mandatory here, of course). See above for details.

    Record definitions

    Here is the definition of records used in callback modules, defined in include/yaws_api.hrl:

    %% Corresponds to the frame sections as in
    %% http://tools.ietf.org/html/rfc6455#section-5.2
    %% plus 'data' and 'ws_state'. Used for incoming frames.
    -record(ws_frame_info, {
              fin,
              rsv,
              opcode,
              masked,
              masking_key,
              length,
              payload,
              data,        % The unmasked payload. Makes payload redundant.
              ws_state     % The ws_state after unframing this frame.
                           % This is useful for the endpoint to know what type of
                           % fragment a potentially fragmented message is.
             }).
    
    %% Used for outgoing frames. No checks are done on the validity of a frame. This
    %% is the application's responsability to send valid frames.
    -record(ws_frame, {
              fin = true,
              rsv = 0,
              opcode,
              payload = <<>>
             }).
    
    %%----------------------------------------------------------------------
    %% The state of a WebSocket connection.
    %% This is held by the ws owner process and passed in calls to yaws_api.
    %%----------------------------------------------------------------------
    -type frag_type() :: text
                       | binary
                       | none.  % The WebSocket is not expecting continuation
                                % of any fragmented message.
    -record(ws_state, {
              vsn :: integer(),                     % WebSocket version number
              sock,                                 % gen_tcp or gen_ssl socket
              frag_type :: frag_type()
             }).
    
    out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/soap_intro.yaws0000664000175000017500000004127012605311413013327 00000000000000 box(Str) -> {'div',[{class,"box"}], {pre,[], yaws_api:htmlize(Str)}}. tbox(T) -> box(lists:flatten(io_lib:format("~p",[T]))). ssi(File) -> {'div',[{class,"box"}], {pre,[], {ssi, File,[],[]}}}. ss(A, File) -> {ok, B} = file:read_file( filename:join([A#arg.docroot, File])), box(binary_to_list(B)). out(A) -> [{ssi, "TAB.inc", "%%",[{"soap_intro", "choosen"}]}, {ehtml, {'div', [{id, "entry"}], [{h1, [], "SOAP with Yaws"}, {p, [], ["SOAP is an XML-based protocol for communication over a network " "connection. The main focus of SOAP is remote procedure calls (RPCs) " "transported via HTTP. " "SOAP is similar to XML-RPC but makes use of XML Schema to define " "the data types it uses. " ]}, {h2, [], "Preparations"}, {p, [], ["Yaws uses the 'erlsom' XML Schema " "parser and some SOAP specific library code. " "Thus, to be able to use SOAP with Yaws you need to have " "'erlsom' installed. Currently, the easiest way of installing " "'erlsom' is to check out the library from github.com and " "install it from there (you can also download a released version " "of erlsom and install it)."]}, {p,[],"To install 'erlsom' do:"}, box("git clone http://github.com/willemdj/erlsom.git\n" "cd erlsom; chmod a+x configure; ./configure; make\n" "sudo make install # iff you want to install as root\n" ), {p, [], "Important: The SOAP-specific code that makes use of erlsom has some limitations " "that it is important to be aware of. Only the Soap 'document' binding " "style is supported. There is no support for non-soap bindings, nor for the " "RPC binding style. Also, only the 'literal' encoding is supported " "There is no support for 'soap-encoding'. For an explanation of the differences " "between these concepts, see this " "description."}, {h2, [], "The SOAP client side"}, {p, [], ["The SOAP interface is defined by a WSDL specification, which " "simply is a (rather verbose) piece of XML document that specifies " "the public interface for a web service. As a client, " "we don't need to understand everything in the WSDL specification " "The parts that are most interesting is the name of the operation " "we want to perform (i.e the function we want to call) and what " "input data it expects." ]}, {p,[], ["As an example, lets have a look at a public SOAP service that " "returns some weather data for the location we send to it. " "The WSDL specification can be found here: ", {a, [{href, "http://www.webservicex.net/WeatherForecast.asmx?WSDL"}], "http://www.webservicex.net/WeatherForecast.asmx?WSDL "} ]}, {p,[], ["We start by finding the operation named: ", {i, [], "GetWeatherByPlaceName, "}, "which is the operation we want to invoke. As can be seen, we have " "one input message and one output message defined. The input message is " "the one we (as a client) will send to the server. " ]}, box("\n" " \n" " Get one week weather forecast for a place name(USA)\n" " \n" " \n" " \n" "\n"), {p,[], ["Now, follow the reference to the message: ", {i, [], "tns:GetWeatherByPlaceNameSoapIn, "}, "to where it is defined: " ]}, box("\n" "\n" "\n"), {p,[], ["Continue by following the reference to: ", {i, [], "tns:GetWeatherByPlaceName, "}, "and you will end up with an XML Schema type definition: " ]}, box("\n" "\n" "\n" "\n" "\n" "\n" "\n"), {p,[], "This tells us that the function we want to call takes one argument " "of a string type (which apparently denotes a Name of a place in the US). " "Left for us is just to call the function from an Erlang shell which has " "got the Yaws ebin directory in the path:" }, box("1> inets:start().\n" "ok\n" "2> yaws_soap_lib:call(\n" " \"http://www.webservicex.net/WeatherForecast.asmx?WSDL\",\n" " \"GetWeatherByPlaceName\",\n" " [\"Boston\"]).\n" "{ok,undefined,\n" " [{'p:GetWeatherByPlaceNameResponse',\n" " [],\n" " {'p:WeatherForecasts',[],\n" " \"40.3044128\",\n" " \"79.81284\",\n" " \"0.000453\",\n" " \"42\",\n" " \"BOSTON\",\n" " \"PA\",\n" " undefined,\n" " {'p:ArrayOfWeatherData',\n" " [],\n" " [{'p:WeatherData',\n" " [],\n" " \"Friday, December 08, 2006\"|...},\n" " .....\n"), {p,[], "So what happened here? We specified the URL to the WSDL file. " "The yaws_soap_lib:call/3 function then went to retrieve the file, parsed it, " "created a proper message, sent off the message, waited for the " "reply and finally returned a parsed reply as Erlang records. " }, {p,[], "Even though this is very convenient, we probably want do more than just one call " "to the web service. So to avoid retrieving and parsing the WSDL file for every " "call. We can do it in two steps: " }, box("1> inets:start().\n" "ok\n" "2> Wsdl = yaws_soap_lib:initModel(\n" " \"http://www.webservicex.net/WeatherForecast.asmx?WSDL\").\n" "...\n" "3> yaws_soap_lib:call(\n" " Wsdl,\n" " \"GetWeatherByPlaceName\"\n" " [\"Boston\"]).\n" ), {p,[], "To be able to work with the records that we get in the response, " "we can create a header file that we can include in our source code. In our example " "the generated '.hrl' file will look like this: " }, box("4> yaws_soap_lib:write_hrl(Wsdl, \"/tmp/wfc.hrl\").\n" "...\n" "5> {ok,Bin}=file:read_file(\"/tmp/wfc.hrl\"),io:fwrite(binary_to_list(Bin)).\n" "-record('soap:detail', {anyAttribs, choice}).\n" "-record('soap:Fault', {anyAttribs, 'faultcode', 'faultstring', 'faultactor', 'detail'}).\n" "-record('soap:Body', {anyAttribs, choice}).\n" "-record('soap:Header', {anyAttribs, choice}).\n" "-record('soap:Envelope', {anyAttribs, 'Header', 'Body', choice}).\n" "-record('p:GetWeatherByPlaceNameResponse', {anyAttribs, 'GetWeatherByPlaceNameResult'}).\n" "-record('p:GetWeatherByPlaceName', {anyAttribs, 'PlaceName'}).\n" "-record('p:WeatherData', {anyAttribs, 'Day', 'WeatherImage', 'MaxTemperatureF', \n" " 'MinTemperatureF', 'MaxTemperatureC', 'MinTemperatureC'}).\n" "-record('p:ArrayOfWeatherData', {anyAttribs, 'WeatherData'}).\n" "-record('p:WeatherForecasts', {anyAttribs, 'Latitude', 'Longitude', 'AllocationFactor', \n" " 'FipsCode', 'PlaceName', 'StateCode', 'Status', 'Details'}).\n" "-record('p:GetWeatherByZipCodeResponse', {anyAttribs, 'GetWeatherByZipCodeResult'}).\n" "-record('p:GetWeatherByZipCode', {anyAttribs, 'ZipCode'}).\n" ), {p,[], "As you can see, every record in our header has an XML namespace prefix prepended " "in the name of the record. The prefix 'p' as shown above is the default prefix you'll " "get if you don't specify a prefix yourself. This is probably good enough, but if you " "want to set it to something else, you can do it as shown below:" }, box("6> yaws_soap_lib:initModel(... , \"foo\"). % foo is my prefix\n" "7> yaws_soap_lib:write_hrl(... , ... , \"foo\").\n" ), {p,[], ["Some final notes:", {ul, [], [{li, [], "The \"http://...\" URL given as the first argument to the " "functions above may as well be a local file, and thus written as \"file://....\". "}, {li, [], "When we retrieve a HTTP located file, we will use 'ibrowse' if it exist " "in the code path. Otherwise we will use the OTP 'http' client."}, {li, [], "The prefix ('foo' in the example above) is passed to erlsom - it is one of erlsom's " "options. If you want to specify other options, you can also pass the regular erlsom " "options to yaws_soap_lib:initModel/2 and yaws_soap_lib:write_hrl/3. For example, to " "specify how files that the XSD inside the WSDL refers to via 'include' statements " "can be retrieved, you can pass it a function GetIncludes/4 by specifying " "[{include_fun, GetIncludes}]. See the erlsom documentation for other options that you " "could specify."} ]}]}, {h2, [], "The SOAP server side"}, {p,[], "If we want to run our own weather service we need to take the WSDL " "and add our own location to it. Either we can just study the WSDL file to " "see which URL we need to change in the 'service' part of the document, or " "we can make use of some nice access functions that work on the " "#wsdl{} record that yaws_soap_lib:initModel/2 returned, as shown below: " }, box("8> Ops = yaws_soap_lib:wsdl_operations(Wsdl).\n" "9> {ok,Op} = yaws_soap_lib:get_operation(Ops, \"GetWeatherByPlaceName\").\n" "10> yaws_soap_lib:wsdl_op_address(Op).\n" "\"http://www.webservicex.net/WeatherForecast.asmx\"\n" ), {p,[], "Now, edit the WSDL file and change the above URL to something like this:" }, box("\n" " \n" " \n" ".....\n" ), {p,[], "Next, start an Erlang shell and start Yaws with SOAP enabled. We need to write " "the code that returns the weather info. This is done in a callback module that " "the Yaws SOAP code will call with the incoming message. The message will be an " "Erlang record and what we return must also be an Erlang record. So we will need " "to create a .hrl containing the record definitions that we can include: " }, box("1> Docroot = \"/tmp\".\n" "\n" "2> GL = [{enable_soap,true}, % <== THIS WILL ENABLE SOAP IN A YAWS SERVER!!\n" " {trace, false},\n" " {tmpdir,Docroot},{logdir,Docroot},\n" " {flags,[{tty_trace, false},{copy_errlog, true}]}].\n" "\n" "3> SL = [{port,8181},{servername,\"localhost\"},{dir_listings, true},\n" " {listen,{127,0,0,1}},{flags,[{auth_log,false},{access_log,false}]}].\n" "\n" "% BELOW, WE CREATE THE .hrl FILE!!\n" "4> yaws_soap_lib:write_hrl(\"file:///tmp/MyWeatherService.wsdl\", \"/tmp/my_soap.hrl\").\n" "\n" "% WE MUST ADD A PATH TO OUR CALLBACK CODE!!\n" "5> code:add_path(Docroot).\n" ), {p,[], "We continue by writing our weather forecast callback module:" }, box("# cat /tmp/my_soap.erl\n" "-module(my_soap).\n" "-export([handler/4]).\n" "-include(\"my_soap.hrl\"). % .hrl file generated by erlsom\n" "\n" "handler(_Header,\n" " [#'p:GetWeatherByPlaceName'{'PlaceName' = Place}],\n" " _Action, \n" " _SessionValue) ->\n" " {ok, undefined, get_weather_info(Place)}.\n" "\n" "get_weather_info(Place) ->\n" " WeatherData =\n" " #'p:WeatherData'{anyAttribs = [],\n" " 'Day' = \"Sunday, December 10, 2006\",\n" " 'WeatherImage' = \"http://www.nws.noaa.gov/weather/images/fcicons/nfew.jpg\",\n" " 'MaxTemperatureF' = \"51\",\n" " 'MinTemperatureF' = \"28\",\n" " 'MaxTemperatureC' = \"11\",\n" " 'MinTemperatureC' = \"-2\"\n" " },\n" "\n" " ArrayOfWeatherData =\n" " #'p:ArrayOfWeatherData'{anyAttribs = [],\n" " 'WeatherData' = [WeatherData]\n" " },\n" "\n" " Forecast =\n" " #'p:WeatherForecasts'{anyAttribs = [],\n" " 'Latitude' = \"40.3044128\",\n" " 'Longitude' = \"79.81284\",\n" " 'AllocationFactor' = \"0.000453\",\n" " 'FipsCode' = \"42\",\n" " 'PlaceName' = Place,\n" " 'StateCode' = \"PA\",\n" " 'Status' = undefined,\n" " 'Details' = ArrayOfWeatherData\n" " },\n" "\n" " Response =\n" " #'p:GetWeatherByPlaceNameResponse'{anyAttribs = [],\n" " 'GetWeatherByPlaceNameResult' = Forecast\n" " },\n" "\n" " [Response]. \n" ), {p,[], "The final piece on the server side is the '.yaws' file that invokes the " "Yaws SOAP server (note that we are using the same way of hooking in our " "callback module as for Json and HaXe):" }, box("# cat /tmp/WeatherForecast.yaws\n" "\n" "out(A) ->\n" " yaws_rpc:handler_session(A, {my_soap, handler}).\n" "\n" ), {p,[], "Now, in your Yaws shell, setup the Soap server as shown below. (If required, for " "example to specify a prefix or a function to retrieve included files, you can specify " "options similar to what we saw above for yaws_soap_lib:initModel/2 and " "yaws_soap_lib:write_hrl/3 , using yaws_soap_srv:setup/3.)" }, box("6> yaws:start_embedded(Docroot,SL,GL).\n" "=INFO REPORT==== 29-Nov-2008::20:03:50 ===\n" "Yaws: Listening to 127.0.0.1:8181 for servers\n" " - http://localhost:8181 under /tmp\n" "ok\n" "7> yaws_soap_srv:setup({my_soap, handler}, \"file:///tmp/MyWeatherService.wsdl\").\n" "ok\n" ), {p,[], "We are now ready to try it out. Start another Erlang shell and call it: " }, box("1> inets:start().\n" "ok\n" "2> yaws_soap_lib:call(\"file:///tmp/MyWeatherService.wsdl\",\n" " \"GetWeatherByPlaceName\",\n" " [\"Stockholm\"]).\n" "{ok,undefined,\n" " [{'p:GetWeatherByPlaceNameResponse', [],\n" " {'p:WeatherForecasts',[],\n" " \"40.3044128\",\n" " \"79.81284\",\n" " \"0.000453\",\n" " \"42\",\n" " \"Stockholm\", % <=== Yippie, it works !!\n" " \"PA\",\n" " undefined,\n" " {'p:ArrayOfWeatherData', [],\n" " [{'p:WeatherData', [],\n" " \"Sunday, December 10, 2006\"|...}]}}}]}\n" "\n" ), {p,[], "There you have it! " }, {ssi, "END2",[],[]} ]}}]. yaws-2.0.2/www/simple.yaws0000664000175000017500000000472312605311413012445 00000000000000 out(A) -> {ssi, "TAB.inc", "%%",[{"simple", "choosen"}]}.

    Hello world

    The absolutely most simple example is a HTML file which doesn't contain any embedded erlang code at all.

    The file simple_ex1.yaws contains the following HTML code.

    out(A) -> yaws_api:pre_ssi_files(A#arg.docroot, ["/simple_ex1.yaws"]).

    Since the file has the suffix .yaws, the file will be processed by the Yaws dynamic compiler, but since no embeddded erlang code is found, the data from the file will be delivered untouched.

    Hello world again

    The file simple_ex2.yaws contains the following HTML code.

    out(A) -> yaws_api:pre_ssi_files(A#arg.docroot, ["/simple_ex2.yaws"]).

    The file has one very simple function which just returns a tuple {ok, String}

    The String will be substituted into the delivered HTML data instead of the Erlang code.

    And yet again

    The file simple_ex2.yaws returns html embedded as a string. A tighter coupling to Erlang is provided by a construct known as "ehtml". As in simple_ex3.yaws as ehtml

    out(A) -> yaws_api:pre_ssi_files(A#arg.docroot, ["/simple_ex3.yaws"]).

    Print the #arg record

    When writing yaws code, all classic erlang libraries are available, however, the module yaws_api which is included in the load path for yaws modules contains an number of usefule functions, here is a small example in simple_ex4.yaws

    out(A) -> yaws_api:pre_ssi_files(A#arg.docroot, ["/simple_ex4.yaws"]).

    The above code illustrates two points:

    • The function f/1 which is available in the yaws_api module. It's just a shortcut convenience to io_lib:format/2. The yaws_api module contains many convenience functiond for yaws coders.

    • The second point is a printout of the #arg record which is passed to the out/1 function. If you take the time to work with yaws, the Arg passed to the out/1 functions will become very familiar. It is the main mechanism which is used to pass data from the webserver to the application.

    out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/icons/0000775000175000017500000000000012605311413011434 500000000000000yaws-2.0.2/www/icons/bomb.gif0000664000175000017500000000046412605311413012766 00000000000000GIF89aãÿÿÿÿÌ3ÌÿÿÌÌÌ»»»™™™ˆˆˆfffUUU333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,0ÉI§¸X$À»ßIvm^I†Ù °v$€ŽÝû}ئIÐvŠDpHã %…r© ­[§@-45áoJ½Æ¨V1˜z=bõ@æX‹¥`8„Ëo,º@ Û…y_,U€‚IŠJgh‹ŽˆABx–CJepŸf¢%§‚ U«¬TBL±²W;yaws-2.0.2/www/icons/folder.sec.gif0000664000175000017500000000036312605311413014071 00000000000000GIF89aÂÿÿÿÿÌ™ÿ33Ìÿÿ™f3f333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,f8ºÜþ0ÊIÙ¹øÎºï‡ ÷£PËAœ‘;pD®çÁ,¬3Ë.Cp‹Ld²7¢E0hsJY·S­4¹“«Fékýëª~ÇÛn^4Äoö|~f?Zƒ+~ ;yaws-2.0.2/www/icons/mailman-large.jpg0000664000175000017500000001400612605311413014565 00000000000000ÿØÿàJFIFÿþXCREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) Quality = 75, Smoothing = 0 ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ]÷"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?÷ú+?QÔŸN‘­žKr¤»§%OÓéš ×t»…/¡ìÎùýEO4okšû Ž*I]TBæÜ€Dñz⑮픀ׂÝqÍ;¢9eØšŠÎ¸×tëe,÷Ž vªð’™æxìí^VSŒq“ù‘ØÎ¥ÔŠêm -i+¨é÷!!A$€sX­k¬]g}ÊÂ1ÆÞÔv¢O‰¾œ QÌú!ûkâŸÝ©®'„±’z¤¬ð¼[™±Œ ±8ûûžµR]XӋϧj*‚‘)-»ø$Ræ’ݨQ›´j}êÇSEsqøºÚÞAo©$L eÊ®I#ƒŒvýEj®³§²†ûR ŒàõÕH¾¦sÂÖ†ñeú+2Oé1¾þ!žÀæ©·Œtï3™ä\ü‘à“C©Ô#„¯- þã~ŠåO‹šì:ØÛ;0Rs´ž{~§åO~µ¨HÍ=Ï“räË4½¢¦¿Rœ?ŠÔ}w:. ‰X¼Èõç¥WÎœÅ‚ÝÆJýàO­f[øJÚ) Ís4ä°o›ß¾xÿëzU¯øFôý¤˜çõ§Éãó¢óì' *Ó™¿Eþeø¯­f]ÑÜFGûØ«…sá˜dFò%hŸ+‚?þµ?E´Ô¬&k{¹|è|žàûóÎCMJW³DΕ'*sù3jŠ*–£ª[騦]Ï#ýÈe›ðôªm%vsœ¹b®Ë„€ $:“YSøNŠ_&)æ^~Hb1øâ©Í÷oúÄÆ8[UŒY Ì2ppy8ííIo{"k2Þ+{xþE8-!ÁŒžµMí¡× <»÷½4Zùõù}äë­êSè[ÀH±äzçŸÒ¤:¦¨Žš˜=ã[ü)–÷O5·œ×<…ЯžH8*ã>ÙÏòªŽúœ6ÑMi¥;\6Õ\ú?Z›¾ÿ‘|°m®D¾rÿ?оRHÏVœ3ÅsË‹$mÑ”äVwÛÜßM ˆ$X's»nqøŸZ§oaFóèÒµœŽÄ*¿(øôñ×¥R“¿s9R¦ÕíÊôó_æ¿¡¢±ôÍjIåû&£mö;àÅ|½û•ý ·|ŽzzÖÅZ’jèç©JTåË ¢Š)™ˆ@ ‚¨5w iwÛÌöqq†`¸'Œu¥¼Õ–ÂèG<.!aòȪHÏ|ñŽâ¦‹S³”·ŒñÉÇ>™õ©n/FoÖ¦”áu~¨Ï ÙˆÞXùÏý:}:ÇŸJÑ.É5)³;PÝ$prq]‚MŒU%F#¨VÌ”ô‹½9lî¼éä}¬ñüŠ ë“Ǿ e8DZن¯U¿zO§n½uD‰gáè¥1Êi#o-ƒFÌ7r{{ý?*Û³–Ṉ̃Z€<“å¸Wdc‘ÏJˆ/îÒWÔ^o‘­áÀoRăôÏøÕ‹ ^ËP¿óm.ŸpJ2DHÇ<ç ~¹ïN.ÏaWƒš~óz_O#FZÊâdŠ)‹;»¢Œ2Ë÷†HǬXƪÍ1Ã9EÄlrF3ÛÜVLv×é<6Òá¼2*H¤°3ÈÆqôüÝ-§ØmôÕX®P;JöÈÌÊÍŒà`õ$õè>yX«Ñæ²o·N—åøš§W²UŒ­‰3³±Î1žÞ⃫Øù&eŸÌ@Å ‰ðF20 žâ²¦ŽæëQÑÚÙ¯R4ó÷Ë4XaÀÆàF=†EU6·Imoò]>Úï,±#½†éÀǧ­'98ZM+½}|ß——üf}OKšÝãsG#ùJ$·|–ÆxsøÕX´} R -¼xÚÄ7–ÍŽr8>}>µZC:›©©Ü$W9v¸çn{1é×½hi©,š¥íÙ·{x$ ª®¸2œ¶:ŽÝýeùš±ƒtä×ÏÎÞDOá]2DhÝãaʳnÏâ¥5´½K1¤¨“„R 3mÃ'»Xšìlo´ùGÚÔGæfKX‹²äèzÓ”ctŒè׫V|’›¶½|‹P^i°­°‡åóØÇ"l’:ƒÇŽ*Äz…¬¼Â`±#lgçN;×?ö ‰|1{Å:Ü%ÃÉlÏ~VÇ©Oj׊ɠÐbµ¶†‘cA²à|¤ñØÏ?Öˆ·ØuiR_jîöÿƒýy—.. µPÓʱ‚p2zÕQ®i„/¡$›¡§ßévú‘íÿwœluÇøU𦔡€Ž_›®d'Þª\÷ÐΚÃrþñ»ùXÔŠòÚ`¦9ãmÝîMO\êøN fÝe+D{ϯ$œ“Ö®é1_Û‚í÷¢®Q¹öúû÷¡J[IJT¬åJwõÑ–µäÓìÚg+»îÆà3ƒÛšÂ·ì#:ΩŸQt‰>Jž{ä‘ü†*f‚][ÄÁåSö1”DÇ?Ÿ×îŽõ/tÕ¹:6Ù>1¹²A˜Ï.ò»ìk 1P{ËWéÛüÌ»/nuh¯ …¥ÂfMÒ‡QƒÕyààúvã½lÛXÁjfòÁÄ­¹”œìaÏJ}µºZÂ#AîO©îjj¸ÆÛœÕjó?uY[ˆª¨¡UBØ RÑEQ‰R÷M¶¿µ’ÞT*²KFv¶AÈ9õ§Ê54wòŨǔ;Ctäó´óÁäÔWGH@e*ÀF=ê\S6§ZPÓ§ù˜zŽš5±^8K–ŒnqÊ·××?ç5oL½‘Ù¬îÙEäC$â^9ê}—­$ºA¹¼’â{—8â^6q×܃ÓÓñªºÅµÌdÔ`ÃÜÀ@”ǘ1ÏãÛñ¨w‹æ±Ñ‘Tœ¿à?ò}|ÍÚ)±È²Æ®½fŠÔáØVUu*ÊÄf³ît=>è0xÝÅ3žµ;j©xmeY¶†ÚÇäUª¢•JVjèͰÐítÛ·žÛxÞ…J±ÏSœçúW3>±k|wÝ?–Ž Ü>÷9ïüý+¸®ÞÝ/åÔa* $lÙtã‡Ôð>õ•Ek(èz)ûG)Ö×mΗW¼x´¯6ÙiJ„l‘œ÷ùV_‡nu µkˆï.Õ"!ärx?ϨŽ*+‡“QÓôÛH IµÂ¾ô%N>^¹è9#ùSü9 ë*øÛån\*¯R3Óè={óIɹ¢Õ(ÓÃM;__]ΊêòÞÆ6æUŠ<…ÜÝ2jHfŽâ–' «„W=¯çRÕ-4¸äØß33‹qsÀãõ©|&ó®šö³¢«@çhPÁ'úçŸð­ß=º’Ã%‡Uoïvòw·äj.¥fË3 „ÛCýÐs×ò5=½Ä7P,ÐH²DÙÃ)È<â¸ý9BYëòo´Ìþ,©Èà}s[þXÓA¶Xó´ûØÏß9éÅ(MÉ•‰Â”[Of—Þ®]»¿´± n®ùÚ\ã5#\D¶ÿh.[CníƒÞ¹¿$’O§*M$3ƒ²B;¨ÉPFìʪ¦ çÂÖ6ç#Ü}žN7cúã8ùIã±â“©i4T0Jt¡Q=Þ¿ùdPÜîòŸvÆàŒ~tÓh/E™¸O´žDYùºgùW?àÙ"]6îEhÚ5“;â‚1žƒòü+:Xe5fˆ‡Kž ޹?NF(ö•2– >ÖtÛÛoS³¹º†Î6âAyÆO­)¹„[}£Ì_'ßÛ›¯8“GY#q†teaéëYj.š]æ:ª2D$ˆîÈ*y<úG犩NÎÆ4°¾Òš’ÞúúTÇs–‡8aß%sm¥Í÷‡l…µÄH˜Y°H-¼à^ÿ ðæª²oþÔBÄäåÞümÏ¿è(ç•´CxjJR‹¨•›Z§ÑEEs(†ÚI Ú§“ØÖ¶Õì•LeEà•?ˆ qŸB?eÖ¯,º5â͆x”V¹%p0=sŒôÏn(u4ÔQ·%ÊÓWýMM!Žü Êìç=ý};þ5¡UtÜ2ÙŽrÑ«ú‘“üëþök/4¢YL)ÝNÎTàúußš|Ê1LŸe*Õd–úÅÚÞÞÛø~Hnn¦ûeÅàˆM#7È ©b9Èg€jú_Iq’gÊÜy2²ÈpÅ}½‘ëÜÔª©šO(õÒïò½Î–ŠÉðËÏ'‡­^æfšS¿s³'ç=ÏQŠ’)d>!¸ŒÉ!Œ@¤&~Ps×ëV¥tŸsžT\g8_á¿àìiQXsÜOöëø¢œïB3 ^ “…'¡84°—šÖídžé›cÉ´¯Œ°<Œc¯½.rþ®Ò»}¿™·QÏšÞHÈS¹HÃt¬—ŽàYZ4W2—itiÀfùz)5kI—tDe•Ú7Æ%: }Ò‹¿?þ²Ô¯¡2¥Ëtö+ørVm7ÈpÀÞ^@?Îh£DØ—7ð©'d§9í7~üE(|(x¯ãIÿZ—¯4ûkåxòGFY‡ÃòÛçû>úX70,¥‰ c¿·ã“[^tFc˜¾`•Ï?çŠ}7±B½ZjÉéÛ¡›ckovMÍÙž##6G¿×ó®B‰Û\¿_&â?2 #¨~~Ü{Ö»*)8mäi SJI¯‰zއoq6§~ê Í–R =?pjLJÖTÖ.Õ"­Ž££ƒý+¦ª—•ªæk˜Ôc<·_Ç¥J¦£mv4–*Uy’Žêß©ÏÙZÞjÚ•åêÝ\ZØŒ²ŒaTØOrjKUºÓ|SåÊÒKñá¦ð[¶}9ãòü4F¸“I¶Ú*Ÿºà‚3ø}j´ºŽ¶ØXô͹êùéøTÚ(Ûž¬›‹ŠI«Y´­óÜË·7/c¯¬ÑO"ª/”AËp£éúTºF½=¦¼ºMÈÛ»¹vœœâ'¾;Ö¤wš°Ã½³ŽSg ç×éùКÿ–Å.í¤Œ¯Þ doÎ’ViܹÍÍ8¸&®ž²±¯¼·’è÷[°Ë¾æîr¹ç¶@ þžµ ¦—$~+1°u†)šu~›‹ÇvýMuÑMÊ)ÁðsO«öI¾kœË(CÙ¨ÛF¾öpÖ"kÏÅ:Ë<ªl-³ÔñÐqëÞ´Žƒ¨K¦l“Q}¬™kuB3r3“ÎO§ç]=#2¢–f rqB¤–á<|äïfÝûœ‘åð¼14y°Ë°§–IÆžøïœdU½oN:T71¦ÙV5W9þ9ù€8¯>§kb\¶ÞHAœZÌÿ„®%ÙÛlà–ŸáRÔR³fiINœmfßßзáèÌZº–#óŠ»@ËÓ&µ+ž_íû…`Έ6‡¾yæ› ž¾ž}ÑbGɱ€Á÷Ïùâ©JÊÉT §9NSWnû÷::Ìñ&]ïËÀ—`Úzt ã=‡ž÷šÍ˜â«×ƒ‚r;“éžžÕ{MÕ Ö¡š-’E%B:p3ÁúÓæR÷I ÒjªÕ'ЗCbÚ5¶â¥•v¶Ó4û&ÆêIdžÜ;Jª¯’pÀŽ3úÖO†.gCsaw´K„®ÜŽ? ñë]´¢®N#ž•yr»z}åC¦Y›…¡Ý"³8,Ä€X`œŽ”ƒK²YD«Wy¹V#æÆ3€jå|«±µ©üÏï)Á¥YÛJ²C+'Ýýã:ö'Í6çH²¼¸ûDÑ?›ŒnI]?à$Uê(åVµƒÛTæææwõ)>‘a"L¯n˜ î9m£ Îs‘ëSGeor$q… 9å†1ÉëSÑG*ì'VmY¶Bm hcˆÇòFQ“ÀéÖ–(!¶FòÔ"žI©jޝrmtéq½þEÏl÷üOáC²Ôpæ›P¾å]«Í{ $³:†$ú *m #“ 2…yG˜Ê'úQJ /ïUÛú¶©h–Ú“¬®dŠtYbr§q×¥SžÇ\†?ôKåv3ž=ò?_ç[ÔRpOP†&qJ/Tº=Nn9üK"âä9ãÊÏÿ¯ô¦´þ#‘È8B½‚/99 uæºj){7Ýšým^þÎ?qÍ/V¼M·¬jy!ÛÌÆ{ù~UnÛÃvPºÉ 2¸ç€ Ù¢š§É–.«VNËËA©Gˆ«ž¸§QEY˸TS[Ãr›&]}©h i´îŽz÷Âë,†[K¹­Ü€ †![8#¶*¯ög‰âp£SY#;³óéÍutVn”os®8ê©ZV~©3œ†Ï\U÷21ÜK9gƒŒwü1BèÚ„«‰&Tã– Î}±þxüº:(öh_\ŸD—ÈÈ‹ÃÖªêÒ±“±€~¢µ#Š8†#E_ ëO¢­E-Œ'Vu>'p¢Š)™…F–ðÇ)‘#Ur6’8©( i´sÚ­¬Öz¤Z¢ä»*ȼãÜõdVÝ­ÔW–É<,ô=Á÷§ËÍÆùÚÃ̽ÅχnGÚI⬜¨è:ç“÷ú‘_Y‚‡Ú[y£©¢¡·¹†ê=ð¸aÜwSèGcTµ=.RBÓý˜.6Û‚XÉž2“~Ýø­Òç4i·.W£4è¬8µK£<Τr-²\| d Ü‘žœt§ÜëFK+ Kˆ‘ÝÁF'Øç׌Tó£OªÔ½—õ­š+:;Ç—YÂë5£A’ÉÈÃwlãæ Ó¯ËWÝÒ4.쪣«1ÀIÜÊPqi>¢’$êMsSM.µ¯-²Ãþ‰ ÉvÁÈŽpsÓ§¢ûVŸQºŠÒÂxYö¹eÆî3žGÝ÷÷µµ¦Ø.h! ¹‰ÜÇÔÿ‘Y·Îì¶:ã«GšZ.Þe°¢–ŠÔá (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ d°Å¦x¯FFÈά>RÞQb=²3ùPþ)Ñ-Ùž2æGå¶[²³c¹ÈïWît=6ïwh§~7m%sõÁäšd^ÒâÛ¶×;F2Ò3õÉçñ¤ÕO"ÔðVÕJþªÇ?{ãà®cÓ´«›“ûÆ!WðÉÇqÇZšÞËX×#C©ƒ{!N3žç§'Òºk{+[PñGŽê ž’§'ñ»ŽXºPVÃÓ³îõð –:e¦[h‚±ûÎyfúž¦­ÑEj’JÈᔥ7Í'vQE2OÿÙyaws-2.0.2/www/icons/uu.gif0000664000175000017500000000035412605311413012476 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,_8º¼ñ0 @«#¾)ˆÿ0‰Ú‚b•AfhQ#ÌçGŽo@WÓ5Þk((vx¾“ÅHàÕ<Ħ8Œ:ŸÖiõ:N«Uo ¼”ŽÉ1ºk^—…î^;.ß Œø|qyú¥ ;yaws-2.0.2/www/icons/sound2.gif0000664000175000017500000000033512605311413013256 00000000000000GIF89aÂÿÿÿÌÿÿÌÌÌ™™™fff333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,PºÜþÎHø¤-tYC$¦!zP( WÉ›ñEz‘U[Ü4ìÝJÞ쯀1ºT/²g ŠÌOó9T7A‰3‡Ín}7ÑšaîÊŒpÍ^$;yaws-2.0.2/www/icons/hand.right.gif0000664000175000017500000000033112605311413014066 00000000000000GIF89aÂÿÿÿÿÌ™Ìÿÿ™f3!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,L(ºÜþ0ÊI¹¸’À;‘W'bä%„b0l)·¶¬8ÌtÌÃXšiœ{Àæòs©VÁc±(t[ªã§ñ’(ëlŠí¹ßVSª˜ÏhJ;yaws-2.0.2/www/icons/c.gif0000664000175000017500000000036212605311413012266 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,e8º¼ñ0 @«#¾i;ÏäUE®çqe©M§#‘WkË€`( ütÀ Ñ(Q!uA!Ö‹Jq9h•RÄZ-Ýf¶ÇâN¿Á0•\¾ŠÑÊó˜÷ÂÕpðt@ìû‡7lƒ+ ;yaws-2.0.2/www/icons/icon.sheet.gif0000664000175000017500000002731112605311413014106 00000000000000GIF89aà „ÿÿÿÿÌ™ÿÌ3ÿ™™ÿffÿ33ÌÿÿÌÌÌÌ™3»»»™™ÿ™™™™f3™fˆˆˆfÌÿffÌffff3™fUUU333™Ì™3f™f33f!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,à ÿ !Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Ö6£ Ö¹uu _SXœgyfpy•.µE]-:…}Óâövý•ÆÇ¾vk3€dWƒ@Ey$…t^l‘|’”*Šj=z˜?Šš—›(ŸD¢†8¥naZ{¬Lr˜°­°`²p~[€ru´ƒ¹¹j®p±xº³ÂµkÀeÇ™´¶ÆÁ·ÃÕ·ÎlÐÀqÄÍ»µ©Â¼~ÓÜÞäWѲÚÖÒé6ç{ K­ÃУÓgÜŽóž±Ê¬ÜæîžÀS…øåó烙AyÏè«Æ…Cs¾ n"HFP¼ö-xè#Cfó(ÿ’¼ƒO_ª®È¥©1&"•Ñ…›éhçJŽ(‚£62g”à J›Ðè ¤öÜÙÜX“ÐC¡îxd’M¹$’M‰$”L8É£‘?N±ˆDf7£ÀÊ9êX%_}Uf–JX‰£“l"ᦚpžãxNP¦™Rb—V|¹šƒ‚Y炦9è¡mJ¹'ŸrÞH§ŒˆÞ8A˜>§[’(‚*ª•›a%˜=RÚ¨”¬T°««Â¨æ«´Âš„›—fZ+­} é)_U¬‹`[¨«È–‡"¡Š¢™¬­‘¹€¢Ê¾0'ÿ+Ì-Œ¹m2Otš"w ”Aµ—  nèʪ˜ZIm£Ôªh¬7N«E¹å¶Ëµ¨òÛ/¾tû¢ÀÓöê©¿|,¦PÀð0¦LÜ‚›< ¬1 ãè1Áo /ü~|Àƒœ2Á»<ð\F¤„É Ä@˺_\@ÆQ»¼-ˬ² 3êû•Ã0¾|«È&‹Z2Ájæ»t ¸bê­Öа%¸I˜ÌoÄnmQ_œ§ÚL‹j,ÕôRK÷Ô1êë0ª(Ã-ËwoûbÌyûmÊc§Ù„Ù D€vw¯´íuƆêÜ`O´¬á¤Þûò0ÿÞQïÛ¹n ]qæ¯t‘ø¼¯8îxÏ®Vþ”×Cã 9êrÛ{º©4Úͺç/²µÓ¥“Ìwá$gúûõF¿øì´“½8ƹ[O¼ÑH??„ çï½Fž\zÒ£ ^üæÉ“£óÃ#}½¥BÏ!¯Ëå™1ÑQ:ÊüÔPó_úˆ5I¡Ïp!“ý÷¿²ÍZ àNívÇÊQw`âÞø‚ (,-ïjî‹QÖú†5lÅxwÊÓñ@E XÚ‹‚¶¢4·’PsÂk ©&ºŠÐ„:äݼ¶B¶ðUü”.ç»áTì " ز QV@lŸú§EF¯IT"Ízg5ÿ)>ñ[Y¡ú:¦Æ2ЊS|£ív¢0б:ïS}ÐA$ÙŽgd`¯(G’I Лã­%ÈAÆQ€#Â&Y.Ÿ¡N’”D˜%M…ÉLòk“e[¤z4äIMF²”å"ŽxA!°²•Ax¥"EÙY¶Ž•´Ì¥.wÉË^úò—À ¦0‡IÌbó˜ÈL¦2—ÉÌf:ó™ÐŒ¦4§IÍjZóšØÌ¦6·ÉÍnzó›à §8ÇIÎršóœèL§:×ÉÎvºóðŒ§<çIÏzÚóžøÌ§>£“ê@Çfæñu`áXâ&µ&ÒÓœJ‚¡D‘3Qöôd½èS"ꚇÿT/|Êe0j˜~‚Ô¡cÑŽJQ:„Y6´¤‡ …-2Ówæ(í(ŽiT ×ät0âé©OË´$… ‡éÍ@„™o5¤(q B–‡šD1ŸkžÝüè?øµÎy>ôœÓ›Ñ=ï÷%_Õg#ÑvƒN:¸—Hf¡º‡tÊ!ndœUýq7ìôÖ5θ¼[çà;¿üNà:øˆìÉC¢])pµ[ºŽ´yå0@ùRt‡ôÙªGx}Þ\/ÎU¾÷ž^~Y€¯ÊQ6Ç纎ïÁ¯E}z$`àå¸/6b 9É®zƒÂúÁ÷ŒñÐ?[ÒŸ7~íQO•”­ñjŸ»—·=ù\þúØ¿<ï ä{´M°ómGèù¾cáËÒã·wù+W(Ñ‚M·L{ÒÙÎôz ·ÏýËw/s#‹iC´B&æÇÿs²sê·~Xc€ì3€0kïWÈâ*'wg™V9E‡€Jp{p.áC-Ö·}Â1ÿ§Gà÷=G¶¨k¤‚QÄ€—i°vd0ˆ¯}´â`90{ö·|ÐsjJ¦/™ç&x‚z–‚A¨m3HƒJh5çâ*W#"rIXFZ¸%\Ø4: xÓ'yVÈ„eètU’risg"˜u€††ò“…]8‡ZØ7m( ¤„J•tJz86mÒI¥´x@‡z(ˆßc9È„ˆJ†²$}bKf†K“xDñ×B Â`”x+/Ö"%ö‰ Š¢8ФXЦxЍ˜Šª¸Š¬ØŠÿ®øŠ°‹²8‹´X‹¶x‹¸˜‹º¸‹¼Ø‹¾ø‹ÀŒÂ8ŒÄXŒÆxŒÈ˜Œ·ÈzÜñOZ¦pAãÁŒÇÕÔÈB­PòCYÓyF]Þ8^sð§EdþÄR$åŒê(Yã-õQʎݘ/e†CTÐÕU:gEV«À»ÐU±á xvST4%^›Ñ MuzÀÎ7CÅaÙÕ6UU0Ñ þxKó5c5‘™Tüø\ÉøøÎ@X™e]Þø§¡’²5[´õŠ…ZÑZ0‰·åZÈå[±’¤PVó˜_¯e°¥[ÌuG Y€‘“©ÅÃ!””EÄ5,òpÿ…å”7)4)\-¹“Qá”Hù“ÎEQ=É|ˆ¡”¢”>–>±'•+©•]ÙÛ…\t9V͵·Xt‰“‘Z­µ\Qu–v†ÙRÉx¥Q–Õ”bv“} Y#I_çuU´…_[U˜ðð鑱—©¾qSº±V<ÅP»å^䓜K™9”fy]â5›Ó˜¨™¹^襚1µŽò8œõh–ÍÈ|Ç)CÿaçÈQ)õ èø…Â™‘2Ô`.%Ïà؉œ¼¡ŒÞùàžâ9žäYžæyžè™žê¹ž.æ‰ìôb#rb¹ˆ%’NBv‡h@F‹ôYŸç”(|eÿ[¦dªNähKÆdö‰F†âgeXfäEu§ˆ ª ÿ™p ê 6BuV‰ÉÁ&C Z,ø™ŸŸ–xQ6¢'Š? D”v3£2£þµ p£8z£V(3Öpë¶#!JN^˜&{ckãEAJ 3º¤`¤Ð“£PšNZ6Tör?šdضp\Úm›HH#'vž—FYú„®ÁL£hº¤÷¥nŠ£-·¸w¥Hp)ón334X˜>fZZx_zEN³~Î £m+µ8›¶t{@È„†ƒ'w*±Š+¤oÈ´õw¶€›¶UK`l›³•«h4B‡]Ø7s„·)ú¸}‹‚¢K¶‰ ¦‹šºhººª[¸“¸q¸¹[8»[b‡*†Zº1|kº‰à¨À¼iS6Á[¼óêºÞ%K {‹ˆµQæ±™„¼< ½”$½wЉ‰X6/¶Ó‹½Ë‹S¡¯t‰J¾_d¾Éʞ껾ìÛ¾îû¾ð¿ò;¿ô[¿ö{¿ø›¿ú»¿üÛ¿þû¿ÿÀ<À\À|ÀœÀ ¼À ÌXb¦YÚˆPìŽÜ ÿTÁé˜Á¢•›#5_ÜŸ@¥`רœvuÁ#LóíüTKè(˜ÃÉ ôœ Ux8 U ‘Pš¹;©Zw%UAÂ>üii3©I\]Y“ ’·‘ÅyMl&éU&úHÅÍõSUŒ™W5U1ÅUˆ0ļŵĤé~LÁ–†ÀY¦ ^•ÙX’ðX}嘉É_|lÇs\SuYÈ[¹TSéÇléW@©Tr%˜#±Ëõ”ñE…¹Í÷Ç:éZáUÇSÉuìÇaÉ›3YWƒù–ji—ÿp œÅ•õ¥Ê,—L‰U‹õÉ3·Yö5Ë€˜¼…›†\ÊâžYË-ÊÇZAÌ&EÇ_9È`Y\Ê£U«lÊ€ìËý”Ëö(Ì¿%”Ö¼Q¥Ë˜<ɽ|”Ô\΂9ÍâlZù˜z,P¶)]E¼›ÜÅÊRϾyÆ®ÉÃyÏW Ðà ·y›ÝÀ]\К‰•¶Ü1Ä - ÀA“ýÌ=š¨ÙÏ“PÌyÌ­_Î1Á\7CÃA =L”7üŽîXK;*,Á,´–0XjƒT3mÁä˜ ÆÀ@ÔB=ÔD]ÔF}ÔHÔJ½Ô4ÓbN ?P­?ñYÿßêžõ”´""/”cG¶ŸYK`Öb=0´±ò­Kö½ß´aÍœÒ!a„¥]m¡_-ÖvMÖedhd€²ÓÞÖnÝÔ%²ÕrýeZ§v}×ê’×s{ ¡²ŒØ¡p†Fh—¾"q}»†}ؽšØc½ØŒM:½f ʲÀ²¨”ý¯‡v°º¸³"žBØž iÏ’¸¢ÝÖûÓµ’¶×/ZLêÖ÷Š­eÙ'ÜÐú­È"ÝØJ¦Ù?0» Øá{„Ž ´ jfiŠ®¯ÀÚµôÚ¯°¦×ú­MzÒµM¡­Z¨C@ÝÕ ÖúóÛÚ]nìíJƒ»±÷=£Æ-Ü‘ê×ÿ™€ÜôG`‹Z¼`Þû­Ã¾bÕ\¦» îýÞð6g=ßôÝà/0ÜòꨃÅÚ¬=KÔ;-¯o»Ü“£¶ÛˆDSdº«ÛÖü³-{ͬFÀ¦äݤÒíJ4ªºþí2¦ç» ¯n½PÕ*Ïý¹¥ ä=ðà-þâ;ã[lº±3Z£9Žº PذfBîB^â™ëÔbG=]¶+®LáN~EPŽ»GФ6^ã«{àçªßøqæ®h›¦Cnã{†QNiþÞk>Em>ºB ¦Šºø*CW¾¦äMçTkÞR_Ž1&î9ènÚ-ßò1‹p~­¾_ÿ8+çXŽ|TÆ£•Žã$Ž1Q‹r[¾MK}hþé >á¢î²G©KZãV«jjqÛå‡qéC“éGð¦N›ëº^èmwèJN¦>Ù2Œ¯5ŽºÆ^w2¾Ê>³ž¯cª·N†uýéÔNºÙÝëá.àŒ~ÞËQå’=Üùvì{ΤßÊìJpî7~~g¾îMê"ëë#>à’ÎÃÝíß.ƒ¯KX®º>9å.„ÕÃ'ºÈ΃^ÝíŽÝÖÞñE¾ãŠZåÂ>g9Ôéf¼ ÐïÃë¶Ó»$¯¿Û!oæï~ðñ>!ùMÞ3Ÿä5Ï$RÕÙûÂxµDîàQÝôx²ôÖ"IÿßZ½­-Ã{¯ŸunJçJ-ñ½­"‰¥j‰“øõß ù ÞH¨LÝönÿöp÷r?÷t_÷v÷xŸ÷z¿÷|ß÷~ÿ÷€ø‚?ø„_ø†øˆŸø?TÂ&ìÄ ÁO›lÒü…};~ˤåøñÈ_’ßÁ¡ß_Lœ‹PúÍLÒÿ•ë8Ï(Ç oœ©?0L`¯ SkìÃ&åÆi¹_öxT)¬Ä—9WOu˜ÁEÈàÂû •Ð)ü²ù™Fuü¯ùÐ~übý?÷¿ úú HŒÁƒ~2+¨ð!Ĉ'R¬hñ"ÆŒ7rìèñ#È"Gÿ’,iò$Ê”*W²léò%̘2gÒ¬ió&Μ:wòìéó'РB‡-jô(R4–2mÊ£Ó¨K¡JuJµêÓ¤N°6Ÿã+Ø ¹fµXÚ´jÏV¸xV-\¶náÆÐÖ,ݵvµy›×î^‹»ƒð†»ýæ•‹÷/àÀÓ}«x"庒1CŽ|ù#Ãp™õn–8¸p„ÔªS8˜3dËÿúý qtÚÚq£Õ=¹·ÓÞ¹CнÝÙ÷Ä0o¾ õ Ûßî ]ÚxìÚ ˆÜû7Ú âÇO`,}úñµà+ðà½ðáËìN/ß4âåΙ·F|¾uÕÅ÷gÛÿi7Ak$¶ lL`` *¨`ƒyIÈ D–¹÷Þh]H!G;ÌÙ‡¡’ß~ü¹ö=B—V‰Bˆ`X >h`v–ãb½qt_…(âl‚•Ü úíäk:¾xŒGêa¢åœ‰˜øõ —UV‰e…8—˜NVÀšhªUfFRÖ×™˜Íe)‰kJ޹"l_°çžlb·Ý^Ð]œ ÌYo|z¨~- `tÏ- Û™i2 è¤mº ¦Ê™Š)öW‹ï¥§Ì1ÚÆY€îy@ „йªR|bŧ¡°ZÁï=º¤³†Ù©¢¹zÅ#§˜>ˆ©± Hì¥ÿ²ã"±¸ÒúÅYdw° úÖÍ·g‚šëèµ^XVÁï-eí°Õ {‘aé²ZíÅÚË bõâé$ªòŠûP¶â jîÙj0ðX¶",(¼:Úëžîº } 3 VÄ‚6b§7Ð1Du®¦Ú¨Möø"ŸÏ2ŒŸ'|€ ïûDm ë\.ºœ _»‰9u³‰2KôÈr&2•#Ïël’)>m¼Õ¾LyGP5_  ¼ž"]ô¬írì~cÓpjX${,$^L7ýtÉ¡.ùïÊþº­ñ«åºu×^«]ƒ_~øá{£7±Ù†*uØGo´éÒMH÷CuJ²´éÿ­o˜4¸à j@zà(¹]ì¶ûnŸƒ¯­èÈÇ>dÆK“7Þå˜+¤ÜæT\ïê`K3é6›ŽzàÅ·;¯¾*ì×ÏGî<’ÅŒovVú~æ¢â=îõß³Ž)òÉWo*Ÿ§»_sÍØO‹+¤'𠺓{Ö®çíåž¿²ª„?gÙíNþÉñú·2Eqˆ[ßüÊg>ãáª9b«± ˆ$)Ë{ ,Ù ä%¼^Oƒæøœü<'Á Z¯|&$ ?"Fî…áp¿ÀÊnK‘šÔ@´^q?B¼ ‹Øœ#,‰Jü_|èD%2ñwýª—‡øÄ%öÐþ‚[ÿö¾¨=‚ˆ‘Hac½XÆ.¶€,Q©ÈǘÆ9Ò±Žv¼#ó¨Ç=ò±~ü# )ÈA²†<$"©ÈE2²‘Ž|$$#)ÉIR²’–¼$&3©ÉMr²“žü$(C)ÊQ’²”¦<%*S©ÊU²²•®|%,c)ËYÒ²–¶¼%.s©Ë]Σ—r,0ÀŒÌä<øå(¤¡LdÓÆ&=ñ¿90“N½f)úA0Ò!›%ÃfC¢Y xåä¤2Ù¸‡s$ÇœàÜàÔÉ‹kÞP¸FîRqŒhÐ'öÐç4ë9‹uúéȆ7Ç Ðj&m Ý,è>óa„„þb¡öBh0+ÿÑ€Žb¢Á,†EŠ K” ã´f(¨ qÆ€Çt;Ö Dl£2•‚J¡aÓ1à´—ÈOWjÒyò3¨¨ÈéOoX Wl¦q*Rk 1ès:}jKûÙÍ«5«õ©T»š…|Òô¤bU?µ*T¥zu /]ëNSjÕ²Ur¥ëØnJM¼Æ4¨Šà«H[úW°š‚Ý«%ÂjØf¼3e,8 {Ú3›ƒ¸?)늪æÕ£Ùð,f%:‹·ê‚«ØíQŸ‘T›¢Ö¥]-@Z‹ˆc(¶££}ÅmkÛLÃNµ ]Ì’Ú€ ¾d’‘¸Ú4.KQzÜÌÖc!¦¡ÓàBÃÐÿÝ&íwеn;¢{]^r·»Þý.xÃ+Þñ’·¼æ=/zÓ«Þõ²·½î}¯©Üx®À·¾µ~ó›_ǼI¿úå¯}L6ÿþ¿cŸa<#àŽÀ6p}Œ/8Qæáª ta WØÁùQþ8âcq”^fô߉q7ÝÌ¥xr-ÆàÆV t­`j”C’e\ à—›Çêñ‹áÈã È%6Í}¼Cûi{Îo“Módy‚A¿7F§••Œåk99Y²”¹ f˜áAfÖï§t”`(«J0Oî±Wr\*¿@Î].™Çü»<||ÖñŒËL€ ºÐ´a7βf4SÿyÈon›óüáHùÎ~þ3 ùIàÁqÓÓB-jQ3š3cY©·üh:;ZÌV¦´˜-MFO_9s´–µ6o­gö‰gÔ¢”Õ©è¶ùÑ6}ô«½ìéM«ºÒ¸Ž©ƒëÕìX?û ÑæôÊ|=êT÷Èq;V°§ýfy¶úÃÑwŒû m]ïzݘÎô'®ýiÈõZÛÀƯ±l|“{ßpVö¾ûÍnu[{à𦓼k=kƒ ¿Ú&u¸ÕLln;Ëß8²pt§[ãÎnwÁ?r:ˆÐöö^¾—1lÛQÏþöøª9~nŒcÝÒ¦ùaóðP·œoO*7 sqXO™èÿfõ”GrjÜÝ9‡ ¡£nèž“ùçN¹¦‡Þi­Ë<Ù]W:< i4VèÌä7Œ‹ôqÇ™íôŠùÛ“Þv¦ÓYþê/²±®%‹ë=ë3Ÿ;³ÛTtÁ]#­V8Ôn>™)±ŠÓa<599Ë•çòå\ùjÿÛo+£×hx°³¸é‰?xLIßyÓƒõ~=ìc/ûÙÓ¾ö¶¿=îs¯ûÝó¾÷¾ÿ=ðƒ/üá¿øÆ?>ò“¯üå3¿ùÎ>ô£/ýéS¿úÖ¿>ö³ß{>“¢ufqމ4ijOüþ[¦ìÌ_Î#D6¯ïŒ'4gèˋڢœì|naó?Ü÷ó»“«ÿ«þ%WÖ]àC`ÔW©Z]h=ÔF¡žêAÑVD 4•* -¸^frà'(d}  “j}$l` zÓ² Im“ &„^a`90–J%V¶ƒQ¹–Ú JÅiédÝ #áþåû!¡DÁS Uº–gù•[9•oQÕ.ä\a!öU[iá>ÖPáÔZ¡ &¡IáÆ%dàkéÖAáB3¬"Ñ "f )V—e9“!ü-ò u}0.—r V±üÙß8 Ó2¦Ä¡H—ve—ÿùV4Æ–0:D›è¢Ù† ö}#8†£8Ž#9–£9ž#:¦£:®#;š£X‹È—[Èc;ò„…] €ÁØ>ÖãMÜ#>n„AÞé£ÕOÝuc<`íd@¢Ç@$?ÚÅ (€à †~òÕ†Tü†%mØ’ýWEBÀEjŠBVaFßíCj“êÏL’œ¥Èˆ‘ˆM†äc–) dFf×PbC·´dš¹˜‘%t-åJâçE]xÿ›â‘UÚXT&ÚÑeP^äKfVLÆ¢KÊÉS^VÖÃÇ^Uæ¯l¬@aDYÕy˜\ž•q¥xåWžVMÔôȉäáâužÈ‘ØÝq ¯ €¼å`ðXR‡ã ¸=¦“ÝeW^$ÚfXÎ`F Ú,ÑÖ‰«…Snf‚^ƒ´%c6fÄõH=Kk’Oá%ff¦‰ ¦] ÍR Y]^šh~žHâf4‰^jzÛ[Fl $Aɩ٦lnm¶Ú^Ú–p²µEÚØœçµÞœmgéçµåa8Útb “xÛÕ5œE§Ú©duJe‚´$ãÁ\išæ)Æ:Å‘zN¥[Âÿ%y6zž¸9geB'JÖ&Õ!Ù{Â'°,…èŒIy6xžj*è„V¦xúgrúÜ£EèXPæ%ÐÝêõ%70Æ`0Çñ‰¦~žÙYh…’O†ç¦]‚tB ]vã‚ZgU€Kц–èŒrç‘~g’’™¶dKÞhIö(gT€ÜÏ“yè}2å½|Ø£©•(’f~.©’Šé%P‹žß5\b hzºçF h¸ti{ŽiŒÂèZR¨™Êf‡îgÞ±©›¾)‰qc\֩橌zç¢ÎÛ\¾–âÌššÚ¾Eªsª9© †£â©‰Šb§r(¤úiŸâh‘âÿ¦ú›¥r££zjY†êX@^ ›¬¦H`Æã©èSj­‘Bž¥‘‚°º(™Òä…†éžF‘~ú#³6«³>+´F«´N+µV«µ^+¶f«¶n+·v«·~+¸†«¸Ž+¹–«¹ž+º¦«º®+»¶ë¹r”ú!cz`;å_¼&aùÅo]áü!WCõ+1jé1 ¬]Ù`ŃzŸ2“ö_0îC&D¢8¸C@̉ûEl2NÖ.º¢ò¢AâÆ. ’ઘBbi–;…È~ˆ_J# ^ ¦l V×̺ +–ʶ¢ j`ÌÂäÏŠ,Ì-2ªŸ&,aTå¢/ÒlÇ2"¿~ÿ¡d½l"ú’Zá?b8I-”ÕÂÖ2]-ZyíÒ²âlq²TÒV”ÖböàVm8 âÓVm#píJ}-,JC$8Ö6µm2ömUáÖ.6 nÉßBíáª`©­ãª!ãV"b]âIQâ9ÐmI¥íSõ-ÖÆíÞ¾çJ"è2-Œî¦¢áš ØN 4­®OYîã6b!æ®,>ñ¢3ˆÈ/ânâV .š-Ä&gù -Ú-6fTñÒïB”ðúƒkå–îjáòÞCô.• ¬BóRàó¾b/rop9o.ô.J¤Æ:#I\ËøIì5×Iìê¥Ncò¾/üzQoÅâ1j,‹Ñÿ¯»ö¯ÿþ/°0°põ½ã|a…ñ)ð<’ÅWT¼Y?údÁãÙ§MÜ#«Ð“U0ŸúW¦ƒÉFAаDvÄed‡°ŽPdÛ¤œ)Ø ?X ‹ïW ï—£˜°ðŠ@Øœj„CÞð‰vœw(±¾yØ„Y0÷pˆµÆƒ¥°W ±aª†ÓË„q„ qS±k¶ IJ±d…HN:ÿ$È…ÞÔ´ s1§ª†¡ª : @÷tc¢¼±¨> OÞªuÚ!“™£!g«érfÙÿ0 à1’èñW81?…ñr•à ÿè{ÿ¸=2|\ž¥K~&ejLãÛ+i°ŒÀ ñƒ˜Xì1Æp26 òxˆržI ›Â¦,·ÙðÀfo>9©œdgè,“Ñ’L çr.§n~ñb¨J0ˆ€‚&m@²++³kZ15«s3™;+çXªJ:“ê¨&G Bš6ãr%sjVxó¸lÀv 3”ž©ƒòÔ3¥’&“©§Þ€)Dþ¥ªHt<²”šF>À>À6 YY/#JuO•$tÀ¬ê€™óA#´+ï§€^©=Ãtž $E§©M>´MßPFs4?ó´‰Ù@(yl@Bç¨õt8s3éŸ"Т¡ÿtø…nÖtNk¥ªª°ÞFwt~*Æ&·±I7'T7Xk„s ·´©%†5gU/ñU7È&[D³Nµ < ^Kuû4W#É]@‰ã„t£H¢ô@‹Ç8·u -Ú©ê(šÚµ}X“âõdÆôE˨èP²gs?wµ ÌJPó u"“4b¿´b«\–Ét”64\wéƒ6?6•5Å`(š%ç6&+é_µ“̳sÈ d·Ñ‡ uBSÏ1³\c·P}.7$Ï)ìv*ß3TÜ6Ür~‚¶WG‡`oéQ.@¸„·t{p…uV;÷üØÏZÝp“@ ¥¶(ø/Ë z{p]+¤‚pÿä^ç¶—yÛetE…8)aÈ6‡~?*kçãĵ·jKºvkojuÛr%ïv™v·[WªeC¸K8 —j„¸]‚8¯pg‡ÑTÄ餆øx«é[³x}ŸP¯:"OËŒsxœÞ¸®bCQ†üx{Ž7Ú‹º**›Ò²&êÓ!9)ƒê"°”O9•W¹•_9–g¹–o9—w¹—9˜‡¹˜9™—¹™Ÿ9š§¹š¯9›·¹›¿yüžo¦Õ¢¾òÁ£ÃÞë84¬/®/ä«ÂN’‰ :û‚aûªD÷ÑÓÝVÃù  *:% ¢âgéÉbìÇjÒ.•[Ý,;}lÑ‚ºûÞÿ‚ñîl¥lÏâ V–Šº"vía‘U¨W %ílëªz òƒç®m6ÕäN-ìÆÕüÞöÎ"¬{év¯å !Ö–mý+,ïñú!ç~: â!æíêû䲕Š _m¯¶×²?¢¯Ïîâàønn&n((û$.»®_-¯¿Sa®·#¯°¢KÝz¼Ã)à{êÞ.8ð:éæ:'ùañ²:÷z¯ð6å[>-±‹ôy~}ÕãoF`gÛ$ùA•~éÛ½ï÷~ê;ËÁÌê¯þ¸¾,1ÆRÓ5C[Esêíç]5“Ä<¾ï_?·`µ ô=ñëýdƒ'’±Y_GéU>?ŒNpç£úkÓÜ÷¾õc üßw?ë‡ÿKäÿåÛQ÷€ÿÿ?LEa”扦êÊVÀ /ÛL¿2‹çzJ÷Û ž\¾Ìö*W›Ëëâ|:§( ¹Ìš‡´ë½x½‹Læ¦M«×ì¶{T˜_¢‘{é:Ê| ä][Ôó§D´1w€6˜Ó$õ$E…µ¨ÂÖ%uv6Iù zGZJ*º’SÔç‡ÊèóªRXt¨8»5µ å{•«{ù…ÙuV†¬¼ jê\º¬úÒÓã[Äì²çs{ÚdõHþ *ž9V|pÜÉ ÿW÷l:=×ó Ÿˆˆ(Ù+qG"óuáÜ'q`4}AV&ƒBy+æ 7!£ÆŒpîôý8GàÀ~þ‚IéJÁ*½ Fš¸˜ºMfj´ˆ3g‰:ræð„wR_È›:gD)2¤^L«´12 J,Š5ëÎ8‡Dxܖψž§Z?™Ti•(,É‘…*õ@Õcß–½+*cׯ`‹·/Jkül™ß܈fª2¶8òŸ³i_XYò¢Ë!ß™ÁÖeBÏŸ7Эi“´æÕZ(«nÃykT±‡RœAîÊë?3W1;8í ŽWؽ¦ñâÌ‹Jyóé žWÔV;ôí KÊ#)‹{wðÀÅ›?>½úõìÛ»?¾üù¨B;yaws-2.0.2/www/icons/right.gif0000664000175000017500000000025412605311413013161 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,+Œ©Ë⚀QMZÏÅyóè}RØ…¢ežHªjfõÂ^ölt=ݸ^óÔ;yaws-2.0.2/www/icons/dir.gif0000664000175000017500000000034112605311413012617 00000000000000GIF89aÂÿÿÿÿÌ™Ìÿÿ™f3333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,T(ºÜþ0ÊIY¹øÎºïEÄ}d¦)Å@zj‰C,Ç+ŽõWž<œì IEáqg<²‚N"4ÚIRaV˜VÅÝÂx‚Ôl<&€Ãæ´zÍ#,LðŒ;;yaws-2.0.2/www/icons/erl.gif0000664000175000017500000000034412605311413012626 00000000000000GIF89a³ÿÿÿÿÌÌÿ™™ÿffÿ33ÌÌÌÌ™™ÌffÌ33Ì™™™333ÿÿÿ!ùý ,@‘pÉIg»¸-ºï *$sm¢Š£©q‰Zƒ¼`hw ¦IHȤra~PÛe6ˆ 8 Œ°¸)t ! xê ¢¬‚š=Sۉͻhc½Ò>8:~5 …  LŒM‘/IM*†5†/xm˜‰syz¡€iCtX‡£1m¬¨2c³´2;yaws-2.0.2/www/icons/unknown.gif0000664000175000017500000000036512605311413013546 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,h8º¼ñ0 @«#¾i;Ïaš"¸QåyŠ€Êµ.J 7±®0Ö§«Ò#é$ @*í,KëûÕ|¿'ˆÍ"-½ŽóK<%ÇÕ$”ÚŠÙ`ó[Ë“¯éj%ÙJ†c_‰m…ðO­·–ü«‹Çƒ‹™DìQªÁ¤TBP¡I+ëLÿ4ôÄiL­’T&Ôq&Ž‘f.‘À‰¤˜ž?äô;IÔŠ‚yÁ$XI$ÍfzÈüÁã!¢4VÍl´ˆ¨h²ä >9 ê€ ¨´¤¸Õëk ~@*¶îˆag&˜á– ³™Q`58GÜ,õÅ"ñb»Oè|¤w¨NȘ3CFðgmÛ˜zNB>Ö·ô’,Cý¬¥x%ª×Ѧc•ÚÏ´UMjuQÅ:V%$ØË¢’€2z*›(c ¤­ž©câVNƒ%h—°: ÌŠ8Xís白dÍLŠÞÜt ö\¦š?ejõ<;²þ0¤rúí™”R)„\!s×Ìwÿ~ ò–ÈCÓaÓƒz–f$ˆ³M5…„ ޱo©’Ûr¡‹Ïa8ƒ$)Àú}È„~Ÿ¦Ñr6±8 (%À,ºh$ é!2™ Lň d%aI áÅ`Ä•á@—Cè²À܈pÃaÇ ¶@‡9^–ÈP[ŠT€±TPª@‡õ#H!ŒEAÂaša™n>á‘GÃ%êè£b(\Fjé¥ÈÙF2ÓõØdt6'Èœ ! Ó™Y“¡µ™~<”ã„"ŠfW!­–¶©U@nEA†k®nâÉT§ŽĬ¸ˆ –±¶zÉÒÿÌÞ–ÚšzuEŒ5’RC-AaYÀªJÕI~åÂÒÒ©#$9](Àéœ$žû•J XõTK6É÷J!¿\œr“$©RúKЀáÒi%ÛJh8Lõ£qý‘@²õ–<¬ÅÉ´X¯\”[³îº¦§V<(irœ¦¨·2ËŸ¤ÛB€Ô®TÛí¡FíÊ‹*:IÜ Êy t¢üfÎüqMƒ‚ð+2…Äpˆ˜‰ÀÖ:LçñÕ:mR¥*è¡©\ÁC×vó„NÁÝÃ….溽lU5õ sÛªXm°¹@Ð ¦/¯}°.1sUÍ&î`p÷ŽÝbÛª¼¸Œy Œ £&K­$sow·+:vÊðf5(à€Õ‹ê«Ï u-ˆ„bnƒrwÙICó ¶¼‹Ãáp l÷¼o?¼íVÂÊa¬-™siÝå#¸C[úìX@Èô(T?u ? NÝL‡¤3Jh‰ä§ºlcmÜàL pÎ0dk ÇPäF? œ,åq|®‰° üKÃ3Ž7lC'”Ñ< A.!*…é»ðèwÁ3Ð@pŒ# "!›)!.[H ¶!ŠQ`ÌÀØÕ!#°¯‚&¨Þ®ƒuá°>†¢·ÈÅÌ„;yaws-2.0.2/www/icons/movie.gif0000664000175000017500000000036312605311413013164 00000000000000GIF89aÂÿÿÿÌÿÿÌÌÌ™™™fff333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,fhºÜÐáÚ4%^Â;• 1œè.ch˜é ^íËn»ÀñªÔ^j&Òoª\dh: `…A3¾<"f©¢|[’í¦•zqUÒ 6³•â#ÎxÚ£Ö©"íÒƒ„ ;yaws-2.0.2/www/icons/apache_pb.gif0000664000175000017500000000442612605311413013753 00000000000000GIF89a ÷ÿÿÿÎÎÎ¥¥¥„„„ssskkkZZZ!ÿBÿ1½RÞ­„ïœBÿ„ÿÎÿÎÎÎÆ½½Æ1ÿcÿœÿïÿçJïÞ{ÞÖ¥ÎÿœïJŒÿc焜ïRcÿ!ù, GÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢E†0°À€l0°!Ã(Q&XÙÀA„þý3ó_™hþ; ¦2 ø°3€™=e%03PpêüWèL«¬Þ´y±«×¯`Ã|IvƒÙ *P 0aÂ? J㾕@wÛµ2PÈ0!ƒI¿Pþ;™._Š]̸±ãÇb#Dh0Aƒ• R Nùσfý†ö+Úd^½¥Ófð uëÌü'€£À u'HhÛ–îîݺ%\0xaíÚá/^μy 5{XØA3†‚0¯d¸@{‚ƒ ˆÿoù«€óçË/Œž ûêãËŸïðåy¹oç¶]›!oß½L•’(PSQÅST´ $ÀPÅ´ @L)’SrU×Fʤ} †8_°Rg •dÚrT`×ZnY…Ÿ\pýö[¨5À^˜À-¹ÔPºµ€¿MðáAÅGÁBN"‡ÝrÃY°Üu I·Öaçw_Þx"–iæ™h¦©æšl¶é¦A.9Ðy(æ€ àÙPMXÅ‘Q `ßO/•SE€  €Sð @|E@@V2iøÏŽÐg¢žúæ¨eUP í÷_*J§RMnÿU…’)õNEzIMÔè=*S¢Viêé°È('©Ìª÷èO_ÁÑ8—p—‹¨M0a  È’x†!°¬|[QÚìº"•’Y¡©ÕŸ‹lÁ5c~¾õ¶½x¡6Ò_&ÖÀ¹å; 5éä ‡%B4÷pB¸j±«”f€©xã…,òÈ <†§‰š †’Ф±ÌœqjÝ5ÁOnÙ;#P Ûk­9 ¤ÆENP’ENL '½–ÑÊ‘&åmËe|–mìÝÕXcòÈ"—<ªdHfT!p)àÁ ÚÛðš…ÒqåÀwª{d¾Fÿ„Ap <ÒO7Ä\ß~>7ŽRÇ^~¼Pw’4&ט‹»œwîùç ‡.ú褗Î9ÁaƒMÑÈŠX,A¯›.;D¦ê-)£hk–€e#TÓ±ÿL*—°›eÓ¯É*lRVñtà/U—¦Êoeó³goÐ @@…Z˜4RJ,í~ëÀ?«L’â$!üj”)ŸÏîd?°2q»@¯óÉV|¢½DF·ª‹“ü“šÏx@)0ÌÀjBAÂOW׳ž¤œ·“9 ëSIÉìðã]Ï€( [€bØL)¾‘ŒŒã¯½\X‰,ƒÕ%„= yTWÿX˜BŠ=/éVo^Ã|ÉÐ.}éVÜ4ãÀ6 \zƒÌrRÄ.V*l¹ë‘_ò2öÜk.7z"Û¢ÒÜ\™) ê(R—Â%Dix¼â r øQp 縔pqè€";à5…Pn%$&IÉJZ²’‘´ÈdÜö.—¦E0b"~jd£ýàH-1£@äV°Í\ÉÍo™¤Qà¸Ì¥. —çøe‘Î ‡ILh :)ÙA¬æÈ92L– Ù¦IÍjZ“1w»LW𴍿49B¥] Q&Àá oÚ&žØÀæg!pB´Ý Î–»Ìg”4Fó¥Á])KšY‰È¬ôj[Ï%'™IõŒÍD+Ù JHÂÍn.ç4ýñË^ÈØ¢¾ÄÌ3»U\~bñÀS K’:y“$ÄÙÆÑ#}IS©„j á€"©1ï“Ö|¤ÖÄ$Í .@™i’Lm\麪Ge¥þB’¨¨í„k|ö!ÜGkÂJÖ ,±p¼ŒHÓüV²º5¬Xt"ÌŸó˜šA*J¡™¡~‡¨ã¡¤Q¯éEÚérŽî9ì@0 K`úM—è0'&Y»ZV¯@5+ÍVó ƒ -5 KÚÒšö´¨=@;yaws-2.0.2/www/icons/tar.gif0000664000175000017500000000033312605311413012630 00000000000000GIF89aòÿÿÿ¿¿¿»»»VVU777!þDThis icon is in the public domain. 1995 Kevin Hughes, kevinh@eit.com,`(º¬0ª½ôÉy; €A|–È™,‹¦#ж!Ø„FZ÷)ÏÊÌFb‚¿!FqäÔN=Ï 94ydÔ™âÚÜ];Ý䌛UzÂÏô¹<^¯L=Ùùu{ë4þÒ„TÿM ;yaws-2.0.2/www/icons/generic.red.gif0000664000175000017500000000033412605311413014230 00000000000000GIF89aÂÿÿÿÿ™™ÿffÌÿÿf333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,OHº¼ópA«%Ä7­ÇÙÖyB#)˜§¤VÏÜKxnÔ6Å쮞OL e<¡¯¨,1›«gœJ•Tc/ &±×c±Af€z L;yaws-2.0.2/www/icons/pie1.gif0000664000175000017500000000030612605311413012700 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,EŒ©Ëí£4¢ÖX°· ­qò·‘fhBRò§G=g³üR{þãÝ‚D¡¯ìpHÛ±é|6•Ã)ƒ™sèrT‡Q;yaws-2.0.2/www/icons/text.gif0000664000175000017500000000034512605311413013031 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,X8º¼ñ0 @«#¾i;Ï×U"¸×qDëRÄÏ' »n·–à „š­ò Jn»(¬¤À<:{P¤ôÙ¼VEÚé÷Šín—Y2ºëü~ð¸O‘Ú ;yaws-2.0.2/www/icons/screw2.gif0000664000175000017500000000040712605311413013251 00000000000000GIF89aÂÿÿÿÌÿÿÌÌÌ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,zHº¼ñ0@«$¾i;Ï×U"¸×‰@áTAÈôWüî6,ü‚Aa@,N> ±H™ROÚÎÒ¾FNJfR¶zvñÎÂÀnþúîë+3³àáàâ^Z~’’öþúöÞÒÖúþöèåèØ–ª¦Æ?Eýòær""ü¨ªÒÊÎã"$êììÌ-)ñôô^tvζ¸ö …ƒ‚þþö‚jV¢þ—’9BîìêÎFJ¿jNBø !š(8Þ¾þþúå!j^b9=;þàÐúýurÙ:>þ°©þòðÉ ºpvÈá Ølh°­¯ü æÊÆöõøê—ß(+ÒFVêÚÞ×&üîõž:>þþþ‚–Žýëàð á"âÖÖÞšþæØûMLM§‘ÖFJš*ñkmý768˜‡€ÓAB@´¶¶ðýðË6Aþ·­fvv΂v¾¦¢ô<>¢b^æ êÆÎú‚‚ü‹ŒŒÈÓÑWWX°+0þêéâý íFDýÏËþÀªÝACŒ’Žã{‡‰þòúúúûèîâæñþüÕ))ð´þÒØ²¢£]_^¾""È""ýÈÀþÀ»½1/Øü0<þèŒxnehÑðõRSþúú' ^jvýÈËè.--þööýÑÑÒÎõ_]Š>B¦š®úþýöþýº¼‡tuÂÂÖ””á2;öñýþïÚ wuyýöñNBDýáÞy}~²64üÚÚbfdþjnZPRÂJBþFRñý èõöþÖÏîæâûé æUZþ¸½§¬ªÙWUÆÊÆûýîêþöýzllºþ±¶Ö×Ù¾%þæãè¶@FÔ00’„~þ‹‰¤¥£ÚØÚmln›šœ¶Ž†þÁÅþöè°*Ô °þúþeVX‚FF,X~þÛH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\ɲ¥Ë—0cÊœIÓc¿„Áræدç@a ‚ &q N AA3Ú¦çÍ6Á„ ]ªÐ'ÎÞŒ jèÄ)L êÌ9ÔX£7Ÿ<‹P§Q¶§PE8…–]ˆGò‚¥›·oT¯YíöE(0}i(¦aì‘`6–NéK™Æ‘GÂ.œL9óÙÉ‹g‘TX]»‚5´ÁÚ3XZuÙ¾ýì˜2܆§Ïv>Û¸Í[R#ÛðÍP·d¦ª­F=nø¥{š{J;¬Zß`¥ %z½ S…þN껆 Ј:ÔjP§T €ÊEʽû@sÓÕŽÅ*Ý`¿éòœz ¥Õ”ZL‘õž@´àG AÜ)´F?þg—.ºÐ²X†¢A†œ¬Ñ'œôSF´q"A)®(ÐyϨ! Í,ÖÂd;±C -ÐÁ…$!NgN'T£$‹BÊ-LZÒd*ªX’Ê-©TY%>ø,I >·´³ˆ„3ެS&¼ÀÀË0ä“éó –àe*ê0‰O*àT¹ ”ۨ¤*YJ2…‹½ñ ¿°‘‡Ǩá‚&8Pñƒg„Ïgüài¦¡è£O$QD±Äbð2/°Àþ7„È<¥rÏKDM$¨s† q¸ðˆ°ÂŠ ¡4{ʨðB9ù¨&P ;äóÌ3à°Ó…¢3à Ùdƒ 6!„0î !xÒE,x q‹4·xÁI¹äÂG-õо´À=LÐ( kô>¾¼à.ݸ“Í {¸ãÊ.É€Ãxà³­¢tÜxP "(³C9Ï(¡O(]€ÑHº{„°ÇÌ®¸²2¸8±JåìÀ‰9RÜa/“‰z…0è3Æ(SF þôAŠ$¤Äàm{ŒQs61»³&=¨ÒN Ê”­ f#`C ÍpQ8[hA:E`‘+ãbþÞ!ìƒÇ%—ŒÐG  °€+þÑ mXQÆ@!„)™ˆÀÇ =#‰%z¨±22g­&r‹$Í(SXaʘu‘Œ·ñI>åСDxr÷ çÖì 2Éà`Á;(ÎélRŒódÒF¦ðQ4ÀP†Šé¢h£$åÜ’+žÈ¬A8P³…:kpRF‡ÙÀؽ ó8ÊÐñFAlÐ ÅÈ(6öæŠdlÀtØ  h`)š$ щip ИàI@<Á ÊÑpŠž‘ð íÐàGÀ k%q=A ’ˆ_`153{îž@[PrAå /0Ù ¾` ?ó“ÁáÖÑSLЫà”p‰t¥! ¾\À84@&€!0 ¬ð í`øa}t$í8ô _€·§p‰à ·ð#„Ʋ ½ð [°’œ±wgXôÔþ$¢]CRòpŠ{ãuP>c@^P’ÐÐ ž€ßÐop#åV{†O'±åŒ Ö Ï ¬zS!à ãY` íІèà €”ùJÿÁå(ÁqãȈoPp À5FoXà _ ªà0ž€ ˜` 4`kÐtNYn4Ùˆ#@0G4PÒð jðO2ƒ7Xà ±à@u0 û°ËH˜†Ùˆ)+åYQQÍ; òà\ƒB´a€ ‚¸ ¬0 –°’?³‡ÐAK+!LA$m -ð sp Ë ‹Ã7é" ~ =ÀŠYmþ› h{@e1±œ°ˆÚ™"éÙœÐ-Ë€ ô–7B…ÒÀÙyž)‚"eÐ æ€z@P€‰&3® °-÷YëIº6xPà! c°ݰÞðÏОuž ±"ºÀt0¬ Óa5£_° 4ŠºùÙ zD _ S™Š ¤ ¡-ŠùI:2ð!°‰˜ˆp€¡Íœ;ÊÍ  A:e¾s¡W@ º¤ÚÕ¤As…ØàÏÐ Uº¤ÁÐ ø`så Øp º¦-š\P¦žP—x¡_j¥ 1¦ª`rz™^ÚevZ?œ§ºx‰þ´9`à¥Í°¡Š Úx‰Àt¨Ï@¥‹ŠM ÞP3z3ذ£Ð‰Ê¦ç Í A§›ª7¸0 I)ªzù`ªZJ›´ê £2§i§`±¦êKì²Z¶JÕR©¬Wªpªxƒ È WÞЧĚozª´‰ è§ÏPCÏJ§?D­ÁÔ¬Ïà§ÙJœ€È:ez®y5®¢ ©€©šÊÀ“ª¨Ù œ ð0 ¡c{`à“ª¤Ñ£bdŠ *€ŽrUeà¥-#ÏšŸÁÍp j0@´i3—ùÒ ¡B°øyͰ[Ð *`3›øcÐ ªþ#ìÊ å@ Zà î°hÃ`@ –°²‹ú˜ƒÐ pPe›¸3 .°\`žJ°\p Ô°r*33Ð è ÏÀ‹Ú uÇ TŒÀn71Z‰ î€Bî ì à° å€KË´+±ò1h’'àÐàð ìÐ  p0¸pà „‹ ¹_Àz ê€%b£ 4 Vyö”€Ñdœp $Ðï`h  Е0º¤[º¢Kº  :`Ð^p 5’9Qk,qŸÐí Œ¸»»ÊØ»Ûâ»Àë»-0¹¹:úŠËGð/MѼ A!ÎøŒ  ÚŠ˜uÓ Añ8ZQnB’N‘…§Ç*q¼ïŠw”"ÝëiÁÚe’Ûáª"Ñ?c?ÕQ™±”C²‡áöë{–¿…ɱÀ™1%’–ÆIvû²òT“‘]Œøw|¹F uG·#Ñqgô«ûqÂûñêñ“« ,ì/å§ç%Ág%±ˆÁD‘ c‘H×¾9Ü¿·q)¼Á¡ÄÙj}õCíëg<ÅT\ÅV|ÅXœÅZ¼Å\ÜÅ^üÅ`üÅ;yaws-2.0.2/www/icons/ps.gif0000664000175000017500000000036412605311413012470 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,g8º¼ñ0 @«#¾IºïÀjÜç…U‰ØhºV&L w¾UÂ'¼¦eH{»ž­óã ;ÒeAJ^X*zõ†ÖÉôÕ¬rYDb8Í^³Õç7\(ßÒë7>ÿ€F85… ;yaws-2.0.2/www/icons/patch.gif0000664000175000017500000000037312605311413013145 00000000000000GIF89aÂÿÿÿÿffÌÿÿ™™™f333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,nXº¼òP@«%¾i;Ï×U"¸×‰¨Q¸ð‰RFmòL ü€K@(¬ô~B@É\Z|²€t:}"‡Jª”P@-Õz⊗Ý/ç,%Íb®ñf»“Ë<óú;j:#j=†‡Ô_@Ü9B ç»U„CI`ù3"“‹¥tJ]F«Ø©â™¥O‚x,–~!Èæ-ªOîØÛè»»1ÿièt-)44 ;yaws-2.0.2/www/icons/quill.gif0000664000175000017500000000041312605311413013167 00000000000000GIF89aÂÿÿÿÌÿÿ™™ÿ™™™ffÌf3™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,~hº¼ñ0@«&¾i;WGxp]……BqHå…êÖR/Êí!¼:¬¬’®çûá,C˜Šb V’…%H@¥@“dØ)Ùð6<Œ‚ÃÙ1 ûE‹©Y!ä~˺†A=é÷v,€ipg‰Š‹ZpŒŠ[y”•–•s"›œ› ;yaws-2.0.2/www/icons/p.gif0000664000175000017500000000035512605311413012305 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,`8º¼ñ0 @«#¾i;ÏGŒÄUEŽç‰%«M§+çëˆ÷P@ø‘:”aQ¢*!-D㺄YV•(sŠÔÂzÇd•ÛóÀ;/9hF‡êuÖ,‡Wü^xƒ¸Ý ;yaws-2.0.2/www/icons/left.gif0000664000175000017500000000025412605311413012776 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,+Œ©ËÍâŒIXŠìÅAoê}N(JdDjh:)öÂ!×yt]‚¹~md;yaws-2.0.2/www/icons/hand.up.gif0000664000175000017500000000033712605311413013403 00000000000000GIF89aÂÿÿÿÿÌ™Ìÿÿ™f3!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,R(ºÜþ0 Bä#cTËHÐ\÷má4–ЧQ¥ê’‘¨#ìÈò÷ŹÔ·Ÿlð#mÃ_q )Ÿ¾æ"‡êOŠ1Ûè ·Â`l›B·å)uÆ’xOŒ;yaws-2.0.2/www/icons/blank.gif0000664000175000017500000000022412605311413013130 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,Œ©Ëí£œ´Ú‹³Þ¼û†I;yaws-2.0.2/www/icons/pie5.gif0000664000175000017500000000027512605311413012711 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,<Œ©Ëí£4¢ÖX°· ­qò›(fˆ¦Hi¶.µ²íÇ2^Ÿ7½’r¾Ïf< -¤å(át1F;yaws-2.0.2/www/icons/gnu-head-tiny.jpg0000664000175000017500000000575112605311413014537 00000000000000ÿØÿàJFIFÿþZ CREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) Quality = 75, Smoothing = 0 ÿÛC    $.' ",#(7),01444'9=82<.342ÿÀ V[ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÚ?÷ú¥¨êV¶ ‹4©çK‘ !Àyˆê3úÜÍpº¿Å+ 4Éo,2ÝgjˆTÜ#pA9‘íÇ¡85™mñe­nìF´±k¶)›kVÌ<í ä¹ã$ýî½w§x«L¾XÙ® …¤Èt ‰À;~£ á†FTdVÜGssÃ"ÉŠC2=ÅIQÉ"D…Ù°sÉà~µÎêþ:ðæ“§›§Õ-çVÞA!,FTg÷®y~(Ú΋,ócÏ™*·Ý,PŸ|ÏJétOC¬ÎPF±‡Ë@ÂMÞ`Ade¾ ÚØèw/¨üê »¸¬íd¸œ²ÆƒªX’x(’NIW­\O‘YËr|‰¥Yn.(ç•Ãp©òªÿÃsÏÍF‘àËcsqrÐ=¢Lÿ¾Ub²OÇR­9*ËÆF­È<%áû7/o¤ÚÁ1R¦xÓl¬;ƒ ùŽyÎO4‘Ç¢Á|ÓFâI¶d.ò¬-ܱ$ª7=N æ§_hÿÚ’éâþsfYBœ¬j ³}Õä‚sV/uÍ/N}—º…µ³ìóK*«Î29Æx¥M[N–ê;T¾·7)xáóF÷Qœ¹É·jÎ>Ñá®ÕÒVnŠâD à|ÇÆ s¾$ðTi·Fnï­ŽÐö2JH ¸gFæÀä†,NÞ½—A§G¢øâ;]Fû~—<E»ˆÊ!¸!n•€9䓵¹+ô©6©¤ÁvaÈÛ–XKåȬU×8ç gÚ«ë‡|ú\.Êk±#íR~â;¨ã¾õSøW—cUñ¥½Ž—<ˆ­$RÌ“<®6Æàºœã®á†%¦+Õ”az\׋<[¥ørÉžúìD”,¤nC€p¹ãÌdóŒ¼WñWQ×Ù--žÓM† ‘¯Ìe(ÁAÞX¶IÇ s×Ü×!£ë–®ýªÊfKÏ4:4Ž,:“€O9玦º—‡Q×#þÞ3µ•È™ {_Þ¤p*ù`¶HLnðF=¯‰5ß kW p%ýܯ,¶ììÈÃòAiÏ\žkéßøæËź=¼ñº­Ì‰°YO*pN O †ÀåW¬™Ò8žI,h 1n€c'>•àš›è·º®™§¥Å¤ïòÚK‡Ý5©À ŒÄÉ•ÃprsžF{ˆ.cÓˆ‚(R6¸öȤ2–•ÉÏ“Oñ¼6¶·£iŽÚà<»±€Œ¬Œy#CîëÑMxõΫ¨øSÄú\ÆÎÞæ?Þ:DD6»‰d1Ø+q´ •?ÝÆóüj·ÿ„FçP€Y>¥¦àfp$;°Ñœ0s»#“U4Ïk?tøµ/M=…›.m­mQF8Ìf*~R3´\‚3Î߀ü'àèVH´F×.b·idÒ³ùpD„“´)SÎЖíŠÔð.¢Ùhöþ$½ðþ—¤j—hfÂ&Ï"2I\n'aÚFqŒtÀ«ZÏ…®'Ñ/ÛMÙ¢þlÆÝ‘$GvÉ`›ÆÌ=Û  ‚2;qà/ ß7ö:øi'¹´·†K¹–çËi¥ `Y¶üÙû¹)ëÂÏðÖÓÀñK¯øfãS’[lJÖRN¦7AÎ0H+‘“¸Á8™¬|OÖî-VÝ´ÛA#òÛt€¯:˜‡Œ6AÍPðž•y>©y©jpÜG{ö5å1u#‘…ØW’9§kÜm 6¶É‘ÜòÌο31$’p1É'§eÑ]X¤`†{מø£Gû=œËrc»yˬ XÕŽÅ8Úä’Ÿá F+#Jø]áÏía5ŵ̑I+Ä"•Ý Šry9BHvé^²€mÎ=ê£Z¯ö‰¹US¾.Byݵ²£ðËþuå>6_ˆVÚăO½µ{ ¹%W´?fCöpE2L>mÄ¿ £®KW©Ù[ȾLï,’HÑ*HÒpX JŽsÎÏàóŸÅâ Ä*úÉÓ¬u‹&§ª˜¶ÄhVÎ qøm9'Ò¦¶ŽöÆK[”Ybš#Ê Á{W›ÚøY?á%½µ—G™˜JJÒÇå4$Sáò\'Þlåˆ {;Dû-ÔóÎé!yŒÑF©„‰ˆ9aܱÉÉú­¬ Zc9çõ¬‘ak©s›å¼[gšÛpBçÚ['ÇÜçî¯#³€É!f çrvªŽXõàzT ;9º˜:´ ‘?ê—ª}ù$ŸRG ]8“œñÍe vÛκ‚Ê'»{ge•mä‹!ð— àçžxö©æ–NÖâ K°.Û…ÈÊîSÐòÖŽÁÅdhÓêPi¶eÀU2e·¼,$çÚq»¨Á x;† —V:åõ¨M¸°¾GÂOp#dòÉùÁb2#ªœr:08¥¢¡»ó>É/“»ÍØv H8ã¸Î}x®cU°ÕÒÀÁ¦ùvоÅi$–V¸•øE.ÊA;rw…î*á³³ðý«stñOy÷W ,™r#,ÎÇ<ú}+ƒU^æHú@P EeèÀ\ç¹'W7á7½k{­XºÒŸíí1‹æ[¢ÊæŽ6€æA­‹+EºÞ]ÙǦŠ#y‚¯™þÐþœã¶zU{¿é©© ƒ&­(âÞ5$®GÞcÐ'œò,TР‘Èþ´ú(¢©êhÍ`æ$Üñ••Pq¼© ñÆ?Vêy1º˜î"ùXŒü¬=;õ¨-f–ÚH,®v—e}œ—U Ó®Ò3Óž™zXÒHŒnªÊFa‘ùW;/ˆ­<>ÖÚn±4Ë) \ yN ±*¥U·gå'§=ðãÄðMa$Úvªêpž ²‡aÁî—dÉÿtätê1YÞiÔgÔtÝïH²œ•¸„H’L벨bç9àç d’{eÈ#t§QE‡>Õ›dVÎáì62™b$’ döÀÚ[ÀÛÏa5ÄXgºFDqRÒp¸ Ÿ`{úfmq½#G9 f;JŒý 8çé?ÄqÁÉÇ5—ÝåÕž£t±Àc·)ÆF7m߸žœ¨ÂñŒs“Ó|ÒÑEQEQí#α¨c–$õ#ùú×)¬ørá!¶¸]AÞÞÒæ+¦óy¬Rep¹ÀeÆ)É ç—Óü%y¦x¦éïuë¹t«²gKh€Wf|Îür6©ã¸ü+ÖÓ w§ÑEÿÙyaws-2.0.2/www/icons/screw1.gif0000664000175000017500000000040212605311413013243 00000000000000GIF89aÂÿÿÿÌÿÿÌÌÌ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,uºÜþ0†B‹lhaïB( ]”‰ã@JT¨ªK/9?Ä[ÌÕ\A£ÙŽ@­3$V(Ó؉rR!•v`UÊ©3u|iVf‘àÂÑê*ØÃÚ{ǧï O€~}(„…ˆŠvp_?7 O“” ;yaws-2.0.2/www/icons/yaws_head.gif0000664000175000017500000000440412605311413014011 00000000000000GIF89a <ÄÿÿÿÿÌÌÿ™™ÿffÿ33ÿÌÌÌÌ™™ÌffÌ33Ì™™™™ffff333333ÿÿÿ!ù, <@ÿà$Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,¶„bÉl:ŸNˆdJu@¯X§ƒÊ•0 Ù°xL.›Ïè´zÍn³ȸ\¦tÛïø¼~ÏïûÿKp)un[]ShR] b c€P VW‹‡]‰”Ÿ ¡P‚s¥¦&¢ª«¬­®¯h9„gœT“K ‡˜WP¸žK†‡ºO¼Ã•¸Ä ͰÒÓ}§×D¶ÔÜÝÞß­Ø3 ÍS"µKèó›ÍÈ ÊÍ–œš½Ðè$5ó® A@ H˜`¡Â„´j1œÈð Å‹3æI î»r Y “ð€Å‚‘èJÿ¦0€rŠJ,q½L A„–Ü1P£ÏŸ@ƒ ýö0áwHÙ`G.¤Ó§Øb¢TµªÕ†ÚÉçkаgMœ)ÂDJ#²c%ÄS˜Ù±ž¼Fa{e“1Lrê•BLÙÚ'h—l"–·,]­ š^]̸qU©œPuLjVĘ3kv£¸²çÏOÜ1¶1F›S«~ºõ Ñ«cËžÝÁk<ËØäãr¶ïßMH¹>6ðãÈ1Êrq¹ÍnÔYž{rº¥‚¹”þUoû\|Io‰=9ЉWNe¾½ûV –ŸbϰõÃkêñnR=<à‘ÏŒWu¹½—\|é©§ÿ;¸S F(¡ ¼“ ‚)¤´Â!3•ð€LëÐG‹~(t~ÑTÞ„,¶èâ‹v(„-LahcK“™dÝ/œƒ ?,ÐÀC>@ä9·y–0ÑdY—L‹wø RVZºð³“b¶e„éd"9‰…/a:0‰j6ÁO^iJIf—PBÙ&>s"v¡|öɘ(ù)h K&Gå{½Á(Æžƒ6êè…**é¤Y÷èSÍQªé¦KØfnÚõ!àu‰rj*–^ê{§¶ £ ™¶K©hàâê­}¤ªjHÆáêk{ò•+$NAký \$¿º¢ë®åDÚì´ª1Z‚ÿ´·à²â‡xÇ@ýôv(oÒỶTPʳК€ºð¦†Þ `;F±ÆfÒI]èh_b€‹"³2à>ÇÆ ´{M¯ GŒQ…rÐgo•è›pÀ¶êÅI©#Ý3êt\r¢¬Ä«Ä×°Ã@p1Ê0"޵ŸT"²ø:£³=s¨€À]t¥OŠÇlQ…|ôSíÅSOFG- G,Å2  Ó€ 6wÑ;ÐÒS@ßõKr¿eŒ,õÚl·M†Qa+}õ#%i‡]$ Þœy‰*1%ß‘ô~n'®øo9·Üs Š’ß*@v_ (uxÂx7@ù {[÷€ÿÝF0ÍÔŒ¨GDÔ®>ɇëçºR¦º«Kä¸ã˜^cä¼ch9.[Ë $á|þáßû ¾Å &SžÕÝ/t¹4qÍ™H¨?#Òeôp¥e.[œ%ÖV€/&"[Äu˜úsŠ•ï”»8#½ø'_Dóòü³ü;.¤ëq ƤëÌ%JW⎕ã 1A Ïpà—Ò‚@ÁmMá˨оèBƒt/þSÁ±hfLá£…ŽªÐ5¬Zœ )ÂÚð†8Ì¡wÈÃúð‡@ ¢‡HÄk ß…%1ÁrŠ]Et§¨Š½ì^üÃÈ6FE A1Š,8bLjªÿOÝ¡[{(WÐȸ©/‚qlŒ£LpEG| ⢠äÆ7b€\ƒ®ð®üqì¤Týˆ•D:² X㶈õGJj‘Œ¼–%79ŠÔQ <«Õ!Úó­0…‹“˜Ìä8ÉJ&KŸÌ¾ Y¿5ž©Xa¢U.DA(ä¬c–L¥* ØÊ@¾²ÄDè¶¥…Q2ã>¥q&´¤GŒùK0fc¦…ÉÈó‘žªË ÊJèg;#C2î(%lg8#$`Ÿi“Ç$8ÑùÿÓdg"[ÏúA0„N ñh Oš¸ yÄ*M‹ÔáHÚQ…Š£ -\ImjÍ}±t 3ZY€ÑŸF#SÐEp.ƒYµ4éÐ’šô£ 5*…’VCõà¢pë´*µ†Ämn(¶ÌöÏÑt¡+è$àS²¾jëê LG‹¾NÄ®]ÄkRصÈpm®`RçØj…BÆu @k(`'KÙ3$¤#ƒ ":ŒG‚ÂRA¨ŠF2ÌF¾i³™å¬¬jWÁêÕ:lÞNð?— À³(AF:w)±ö·€¼,’»×B#á, þç9€s-L ëväuáÿ¹(RÞñ×_^¸àuERÇÕÌ*Sёٔ‡‚ép%Öeïm­ ¼è.·ÓÉê ¦W41‘«si~‹Ë´óÚ0s.Ý}\ØÙ”0x¸åd†³ÒMñ¥6L+è·ZjŸñ Z¢\éÒ— %F}å D1ÇáÃfºÞ4ÏÅÎÃzÞ[ÓuæÇÄô!î¦láËøÒR–IlAÆrŒŽí‡d¶´Ogñ\²\žìap€XÄX^‰uÊ1¼ ƒQ¢¿ñ œœ&„q¸l¦l XЂc|œùÂ$s.‰ü ¯¤+Édf²W–h0’ñŃt®Òœtœfó0ˈÆAmñàDó@B†Hlo†ŒMh˜ÎÊxK[.ç{̵{ó=¼A{? Äæ©íèVÇ Âœh´«qPáäŒð;iBb‘ÍÀLMÔ²Çò5^ )l4»Z³N¶zG¢9e÷À›ü]Û•m`Xs!ÅÔÎA,£«igû¸Ä;’¬¿Mîr›ûÜèN·º×Ín"„;yaws-2.0.2/www/icons/pie4.gif0000664000175000017500000000030112605311413012676 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,@Œ©Ëí£4¢ÖX°· ­qò›(fˆ¦Hi¶.µ²íÇ2^Ÿ7]“Ír á €LîŽIä’©D1rROI„á0 ;yaws-2.0.2/www/icons/image1.gif0000664000175000017500000000042212605311413013204 00000000000000GIF89aãÿÿÿÿÌ3ÿffÌÿÿÌÌÌ™™™™f333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,mpÈI)º5W$:ÒàåBÜGZª®’Ù/Œ´ŸM… Pxs’`Éd^z@A¥l6/—å4i½fµÔ®3Êܪ€¨:m5WÉâr˜m…ƒ¹ôøý¼´÷ÛsX‚]nz„T@CŠC5‚*;yaws-2.0.2/www/icons/down.gif0000664000175000017500000000024312605311413013011 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,"Œ©Ëí£œ4‰‹³Æg{Ž|Û"‚¤ø|Ñ(eÕUÅòL×P;yaws-2.0.2/www/icons/yawsY.gif0000664000175000017500000000074412605311413013164 00000000000000GIF89aæ-³ÿÿÿÿÌÌÿ™™ÿffÿ33ÌÌÌÌ™™ÌffÌ33Ìÿÿÿ!ù ,æ-@ÿPÉI«½8ëÍ»ÿ`(ŽdÙ%hª®lë¾p,³fÌx®ïnm ¼ p˜:ø4¢r;ŽsJE †EpR¿DÄAà,›C.x­´ç¸|^º±ï;ºÞ„ïçõv~‚0e@ƒ‡-{ˆŒprIŒ‡g†’xŽ{GPb— ¡,›§¨^¢}©®¯°±²³G¬‡Š¶‚e¹º€¼­N¿Àt‹Â_f–ÆT¸ÊTš…ÍUsÑKF®«Õž¼gLʘ1ÜÍ̹³ç ;yaws-2.0.2/www/icons/binary.gif0000664000175000017500000000036612605311413013334 00000000000000GIF89aÂÿÿÿÌÿÿÌÌÌ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,iHº¼ñ0@«$¾Y ]!©q^¨¥ ¡kêµ®ßjAèüvƒQhè³)ƒä àŠn%Ó–“—¾*Ô‚¥ZUÆîÄ)ô„§´ã9ë!_Ñ8ëÚ³ës˜;¯î‹ J‚I;C‡ˆS ;yaws-2.0.2/www/icons/alert.black.gif0000664000175000017500000000036212605311413014226 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,e8º¼ñ0 @«#¾i;ÏW$ˆàÖ•¦xB.ÀÊQת5³e>–PHðQfÁaQ²vËÒ5 AçÝ’¶\«Ì´­2Á`³ÔIíêØuóût£ëâ»z0ìû…8<ƒ< ;yaws-2.0.2/www/icons/dvi.gif0000664000175000017500000000035612605311413012631 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,a8º¼ñ0 @«#¾IºïÀjÜç…U•(Rª˜'1Øø´0Ó:‹"(ò‚;“ÅHÐñhãì4\6eO¥PúÊ‚¶×W¬£}­es4<®rÛk$œÈžW¸£~_¼EÌ€W ;yaws-2.0.2/www/icons/php4.gif0000664000175000017500000000411312605311413012715 00000000000000GIF89a@@玎4ÂÂDBB^bh¢¢<~‚Žvv,Ž’˜ââVVV""$bbl𢴆’º¾ÂÈ22®²¼jr|ƒ†”NRdrryÚâô:BYVV\ÌÒäRb”FFL™šœ*2Lñòöfjl¦¦¨‘šº9:<^nŒRZxuzz}Š¶ÆÆÈ‚Š¬’’”´ºÔBJdbj˜ar¬âêüu‚´¢ª¼4:WZb”r~´jr¤Š’|ÑÒO™¢Ã>BTV^FNlúúüzz|®²\** Ž’´GR„ÚÚß—šª–š¼²²µŠŽ¤X^hMNNjjtÊÎäz‚±:>WŒ’¨¶Æä…ŠŸMZVb„ââäUbœ66<ööù§®ÌZj¤ÍÎÌƒŽ½“–¨êêï 6>clz®ÚÚP..4 ‚„êê\bf„Š–ÀÂÊÜrv”ÒÒÔžžœºº¼bn§ž¢¼?Fh{~ŽNVŠ{†³Ž–ªRZŒ^j¤íî\dfr¢¢¤ÀÆÔ224ŠŠtv~9BfVZtGJ^˜žŒòöüžž>à…f ~€ Ô@”ø¢Ð!Ä#mÀÇsD¤r‹ÀóûñÉÁ'ðÁßc0à1ž®+œP½4c ãÎ0mF4Ñ„Ñ(g‚å£÷ìƒåÝóKùæëƒõÓ².Û)È:rá=À´ 屯‘„œT˜+jêp›Èúˆ ‘ÆtQÀiÀoˆp‡‘3 ÆÝqÊSÏ_40Zìá™ÉàFÑÊyÃøÇÀ¿„ þyÈÃ/&2å#`‚’ÄxßÀD.²ô±ˆÊÁ¾hà*Ò@‚\1 \ Á!<ÈÀ*Ú€ (T®‡p ºàŠð¢[hbCªp‚=´ÍÈÆ¨ÅÊn˜ …+vЃZHAá´p>t¡†$÷‚š6t  .ÔP HN„t8Á–±‚.Œƒ˜h†/†‘É)ìÅS˜‚¦_`¢ ] E+dð ~¤ ¦(GbB‰übd 0eàJZŒc2 -d ƒ ¬ dàŠ€)xÀ”Ae1L 5,‚wà€<=q‡Z!X#PÐù’~úóŸ ¨@JЂô M¨BÊІ:ô¡& ;yaws-2.0.2/www/icons/mailman.jpg0000664000175000017500000000374612605311413013506 00000000000000ÿØÿàJFIFÿþXCREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) Quality = 75, Smoothing = 0 ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ#n"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?÷¾’Þm¤»Aá“ùÔG\³^›»Ú#9ÅN.¥Ve’Ù†!”äåÒ³ôǪݽ¹‰"u”y„’ÇB5›•®uÆ“”\¹.–öðäÿÛQ¸ý͵ßxÊÿ:Tº¼¸z¤PGŽ]˜Ukm}uBk eÆåûØ sÒ©¾?Ù„¡ŽSoåmgÎ;ÉÆ9â§™½V¦Ê„bùf¹^›ë¡°°ÝHãýO$ª)‹ê©x¯£~a‘ùÕX㺶Õ"”C $Çåý )`XØ lt¨m´™-¼·‹!œ>ã°É¸.G^7}~´ïä.D–²Vô^×ÌÑ:¤‘ae¶%»”`E0k±ìóz¼§%„’K}BÜÉ33C(Èä€3Û×Ô#Ky4CÆÚyYÔ2’Á†:ªýúsKš] Th5yZž…á¬]Ná-¬Xçø˜ñïRãP‘À–êIþäöªQiò½û|±DâìO¸H ªÌpOáO¼Ó®.uÁq ‘ nnFàŽ¾¸íÇ4^VÔN4”­-/ßõ- 6fÿ˜”Ç<ÿžiÑYß[ºì»2¦0Dƒš­m¤0µ–8®Œ`J‰³¶</^Ä“øUˆíµ(' ö¤š"Få`Aúçú~´Òò3”·Jiú¢ü’¬1àY’êRHåU–9ˆ,G®)c#T¿f.¯op£<·×¥Fú3Ë;‰Jº/ú¹–ÁìG·­6ÛØTáNÕ7.=ò4rGµÖM€WŽÿ â­Ì¶ö—± Fu–<$xäÁaÜví]Á½¶l¬„¡èCŒTh4¸aX×ìá%AÁÆzõ©œyµ¹®¿±Mr;?òæszE¸µñLpªœˆ·>võdŸ^¤öîiš•ÃͨB0Í{µËpy#…JºtÑ´ Œ m×fvFsÓ§çUΚ"bÒé%—9>\í“ïÜôïNÍK˜‡:r¥ìïÑvèÛïæP’âM;Zžð+óäîü¼ŒŒ€}OZŸÃû´ûA§˜¢ÜýKsŽzžO׊ÓI´‡Wó¡EiHë:îù±×œôÎ)®Ú ™ä/goÞíóÒQ³½Ê•nh88=R[vþ™‘a'Ùµ›k’†¸,&b¤.æ>§ðãÚ¥¹7šíÆ¡ bÈTĬ3ý?•iÞ_é·Ñr3€ÏN¢’8î$óŒ:lQ¤ÿëÌ~nÜþÔrôL=¶¼ò´¶¶Úÿå~ƒt…¹—D_²4p±™Ž]Iùr~œÔ­.¯ÄÉÑãædcó=)-¬õ(6ÂÚ8Á'hSÔÔË=ùo&æÐlpFä9ëV–‰;œó’s”•šoæVƒÎÃó¼d‹¤î’sõªòIªuæZÕ -9oRíÕò(0¹´¬ŠenR¢àãõZ5 è”zs(¦°|Ȇ¡MDfÈš ƒÅ¥ƒ›ÝÉ’!8&âØùFH6=Räf†›17èdÉÎ6mù¤¸µ9‹:ÖIéÇxÓyX(w0÷îŒ# àâyD.®“+G† °®€l<%Œ¶Øñ HÞ¼PΧxÑibP›Ð¡G’zʱ… K¸àÿ9I#Þx ÐZ@òŽP߈Þ6Ë­åŠsS-"_.·TåH/A2‘à ðà‚²W‡_´ÒBx†GàeÕ’MZåØÈB¨á”G£8±ßà ¥‹‘L7‡BBÀ€•q”VXH æ’dJ ¥“-УÔ$Í(”h©¥SÛ$p€f„|vÀ6µØ–iŽ” ¹°f Ö”B"ZÙEB+v))‚phh T¤è¦ ŠQOY…™pZ¨¨†ÁE¢?tòN©T¼:Ñ2ÇlÖŽnx³Ì ™0$+¦*ì [ôcf ‡\¥¶> Q;ÑÞ0ÿÁŽÀ;CçÎaÆk‚+áÓNj#U&¸>Yj»%ü‡î¸]T!âæ«­½-'b8“N Û#[¶û"†™Âú6,Ó~0b$X!21–Ö æ¢^š˜)Vòy„pŒÝz…ød߈•1 š|w¦D5±O\ óò l™³Ì…hªØÆ@Bq0ñÕÑ+ï/²ÿnÑËÊ@âtFšòbT•-hÀ2Ç‘‹Q’IuÕ~HJó)»1RÈiÔ7Š[»)·”M\ˆ|bá]l“z²IN8íØï!"Z+JÝlÖ…Ÿr¸¡`Ȉpq7ÿÞ[>x‹|a‡"B“)Møsæj p5âžãQ%ƒo)ßS‹çäÓh,`¦jø»²;\B­i4î bqB: óÓÞéìÊCI|Ž]ÅÈ$9‚T}è ΂e.¯·•i’Ý‹a¹0À`¡d"\/R#VŽô¾±p/~6hÔˆ%%-ý"{ìñYût†Í!°,gš× ö‡ Fð ä{œ ±%ÀÐ$IÍÙ’ŠÁ¡¼ …"¸Ó}.è… > µ+\"Úpˆ-é¤Mo ƒ ï€a àþòr—°$ï/4\ˆêZ3Øõ0Z!á†4Wè‡Þ05!0–ñ€QäϪpà ~épŒ£çHG: Žo$@8Ì;yaws-2.0.2/www/icons/burst.gif0000664000175000017500000000035312605311413013203 00000000000000GIF89aÂÿÿÿÿÌ3Ìÿÿ™ffff333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,^(ºÜþ0Ê© ³Ô l°èlÚö™Ž¬l7\'³4kªuÞBë5¯'ÖPcîöR®H¼¢³Sˆ6§ÃÏL‰ìù€›A·²úÁ| † üñªÙ…ïíÛÄÙªâ¸3;yaws-2.0.2/www/icons/box1.gif0000664000175000017500000000037312605311413012717 00000000000000GIF89aÂÿÿÿÌÿÿÌÌÌ™™™333™3f3!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,nºÜþ0†#á´²;DÖ\çiS1ˆcu¦à¦q®ìk„'¡@׆Ûi˜áùX¬ pˆÙõ~%®0B¥CÕŠŒ9½mï˜üÆâ1M:ÖÛÇ/<Ý>Üàn'þ€ÏWû€[2L„LŠ‹Œ ;yaws-2.0.2/www/icons/uuencoded.gif0000664000175000017500000000035412605311413014020 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,_8º¼ñ0 @«#¾)ˆÿ0‰Ú‚b•AfhQ#ÌçGŽo@WÓ5Þk((vx¾“ÅHàÕ<Ħ8Œ:ŸÖiõ:N«Uo ¼”ŽÉ1ºk^—…î^;.ß Œø|qyú¥ ;yaws-2.0.2/www/icons/pie6.gif0000664000175000017500000000027212605311413012707 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,9Œ©Ëí£4¢ÖX°· ­qò›(fˆ¦Hi¶.µ²íÇ2.ïTûE¯¡%a<"Œ¡£‡á0 ;yaws-2.0.2/www/icons/image3.gif0000664000175000017500000000043612605311413013213 00000000000000GIF89aãÿÿÿÿ33Ìÿÿ™™™f333™Ì™33f!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,y°ÈI§¸XÀ»ßEvm^I†Yv*:vD,*àªD ïIÑÿ/Nn§K‰ Ç 0ÐAR³ªF§­Ê¤#UàðAÕ¥r¾â0Ë»¿dvÕ* îxüZ‰0øÿ{fv€€ƒ*}ŠˆstJˆQ•–P>H›œS;yaws-2.0.2/www/icons/small/0000775000175000017500000000000012605311413012544 500000000000000yaws-2.0.2/www/icons/small/uu.gif0000664000175000017500000000017512605311413013607 00000000000000GIF89a¢ÿÿÿÿ999kkkŒŒŒÀÀÀÎÎÎççç!ù,BHºÜ¾ã@k1±ÍJ'Ö\WD¦la Ì4p¥-p„”A/.|s»X{ň<Û$ôŽ•&j(]Rš%v»e-;yaws-2.0.2/www/icons/small/sound2.gif0000664000175000017500000000016712605311413014371 00000000000000GIF89a¢ÿ999kkkŒŒŒÀÀÀÎÎÎ!ù,<8ºLü/— ƒª°ÎœŒ`•I_(¢ê4%‚§£ýÔà1Eä ú€ÚRÜ(އòÇ‘F« ;yaws-2.0.2/www/icons/small/dir.gif0000664000175000017500000000020412605311413013725 00000000000000GIF89a¢ÿÿÞ­ÿÜ®ÀÀÀ¸ }WK;+%!ù,I(b¦þΔ1˜²Ð€2«v$GQA‘¬y6#Ûvð"ß_­ÝdE輞ᷠút„ïø`$eÌÌP 8 —©õŠ] ¿œn„$;yaws-2.0.2/www/icons/small/unknown.gif0000664000175000017500000000020312605311413014645 00000000000000GIF89a¢ÿÿÿÿ999kkkŒŒŒÀÀÀÎÎÎççç!ù,HHºÜ¾ã@k1±ÍJ'Ö\WD¦la Ì6¢ŠÐÅ:T†¼Lu!Ý©C+BJeÎ(›sgiN‡P)òÚî¿°˜µH;yaws-2.0.2/www/icons/small/movie.gif0000664000175000017500000000020612605311413014270 00000000000000GIF89a¢ÿ999kkkŒŒŒÀÀÀÎÎÎççç!ù,KHºLó/ÈIƒ€# À;€Á^‡iä€"D¶£ ±(Ráû©X$ر„x&У³Úä^GY)·´ iºè²÷+›žÎNW “J˜;yaws-2.0.2/www/icons/small/dir2.gif0000664000175000017500000000017212605311413014013 00000000000000GIF89a¢ÿÀÀÀïkcs9!”sJÆ­s¥”k!ù,?ºÜþ0J9ªU„´‘;©A0‹`YY($ÀyZä ²éÞi@ë6Xn°ã ‹·cÐsüœ,ª@X¯X+1;yaws-2.0.2/www/icons/small/tar.gif0000664000175000017500000000020412605311413013735 00000000000000GIF89a¢ÿÿÿÿ999kkkŒŒŒÀÀÀÎÎÎççç!ù,IHºÜ¾ã@k1±Í ÎÄZwŒ^Q™²U¼3‘¥2;´”/3Ò ðSqŽÄG)6ÃŽãœvÃ*’šÛ6x<Ž-;yaws-2.0.2/www/icons/small/doc.gif0000664000175000017500000000027712605311413013726 00000000000000GIF89aò999kkkŒŒŒÎÎÎçççÿÿÿ!ù!þby Martin.Kraemer@Mch.SNI.De,Â999kkkŒŒŒÎÎÎçççÿÿÿLxºÜG˜)§ ÖHúYdmWM]6§e)ØÒºV¬Ìté4+@Då#!d t,ÛÃÐ>kL§K ! ƒ™ô#(›ÍËE;yaws-2.0.2/www/icons/small/text.gif0000664000175000017500000000020012605311413014127 00000000000000GIF89a¢ÿÿÿÿ999kkkŒŒŒÀÀÀÎÎÎççç!ù,EHºÜ¾ã@k1±ÍJ'Ö\WD¦LAšjÀxFlPŠð²meØ ,ÇÞ ×Z ¾ßìˆ*oJ€I,No!α$èz½®E;yaws-2.0.2/www/icons/small/broken.gif0000664000175000017500000000021312605311413014427 00000000000000GIF89a¢ÿÿÿÿ999kkkŒŒŒÀÀÀÎÎÎççç!ù,PHºÜ¾ã@k1±ÍJ'Ö\WD¦la  *BrFÌ à¶2 . ²?¢ 0(‘ç¯5<¿ðYlr\Nï:7š‚´:}T$;yaws-2.0.2/www/icons/small/comp2.gif0000664000175000017500000000020312605311413014166 00000000000000GIF89a¢ÿÿÿÿ„„„­­­ÀÀÀRZZsÆç!ù,HHºÜþ06Qª-o`Á9ÁVtÔaE¬ACZ´ §ƒ0ìpÄ‹ÜeRŽ:•IR4:ѵŒŠ0¢Ep °x\L;yaws-2.0.2/www/icons/small/comp1.gif0000664000175000017500000000020212605311413014164 00000000000000GIF89a¢ÿÿÿÿ”””ÀÀÀ)!Zcc9¥Îs½Þ!ù,G(ºÜþ0¶@ª%‡½ÅxÕf GàT‚¡¤ÙT…j˜å)pP3Åå³ C¬@,1Š•q‰T:¾Ð‚4KQK`G8 ¾`ð¡™;yaws-2.0.2/www/icons/small/generic.gif0000664000175000017500000000016412605311413014570 00000000000000GIF89a¢ÿÿÿÿ999kkkŒŒŒÀÀÀÎÎÎççç!ù,9HºÜ¾ã@k1±ÍJ'Ö\WD¦la  *BrF¼¸³}ΜNà!°'ãQ„ÆcÑè+ žP(k‘;yaws-2.0.2/www/icons/small/rainbow.gif0000664000175000017500000000734312605311413014623 00000000000000GIF87a/öèøøppøøè°øø°ø(ø  ø(øø(0øøÀøHÀøøøˆˆøøHHøHøøøø€øø€ø˜˜øXøàøøXøàøÀÀøøXXøhøøhÐøøÐøÐÐøàøøà(øø¸¸øøxøøxøðøhðøhø¨øø¨ø ø˜˜ø øø ø@ø€€øø@@ø@øøø øø°ø8°øøø88ø`øø`øøøøøÈøøÈøèØøø`èø`øøØ øø øˆˆøøøøPøPøøPøøøÈøøPøÈøØØø8øø00ø¨øø¨ø0ø¸¸øøpøðpøxøøøøxðøøø,/þ€C‚C……aˆaQ‹‹;Ž ; ’o””K—KAšAcŸcc#¤¤L§$©©w¬w0®00³^¶^P¹¹:¼¼¿pÁÁHÄH.Æ..ËhÎh)ÑÑVÔV*Ö**Û{Þ{|áâã2ååUèUêkïk'ò'Tõõ ø sússÿn¼Á¥`A 5˜Yh‚C‡>"úÐC‘b€‹fhœq¥cG =¤™¦I“=Rö8Â’¥œ—䘉£fM'8œÙyæÏI€&:”ˆQ£’‚Yº´ˆÓ", ²`± ê‚6XÛÙº•‚W bÀŠá@–l–³Yj¨U+ -þxâþ˜;7‚Ýeò–ÙÀ—ï–¿[lL 0t‡X¼xŠã)&"›`C™MË:`Ù¼™†gyB‹m§té¨W XÁZ‹k×(b£PC[ ƒÛ Zänшoßq‚Ç9@ü@Žã9ž$ò¤‹sç¢Ç˜>½Žuë%²—h½‰ˆï"È„'CF‚yó@Ò+Y¿Þ{7 à+PÀ£>)ø¥|Ù¿ÿ‚ÿ /8H„T†ˆD¡H#D’ÀZò&Ad‰' ˆ2Â(¥œÂ ®ÒÊ+±` Ë,·à‚Ë.Pø¢Ã/À SÌ1É8 Ì2Ï@Í4Õ\“ ÚtÓ7|€3Α|˜þ#C:ì´Ó<óÈcùðÓ? $A\$¤C =$QDéQFqäQH$¥áæI ¨”RKG¼$ÓLxÚ„CN8ñô“PD%A„ DXP¨` ÚÔSQMµUW]…•ZuõUXcUZi¥Å–[páñƒ¨tÝ…^{íµÁ«þeC`„f!ÐÚX™Yd•]–šu†Åg£Kši¨­ÆÚ²¯i![lµá¶o¼ýf„pÇÜrÌ1÷\tàRWÝuÚm×xã‘GÞy¤§{ïÉ7ß|öå‡_üà ‚`‚Œì…#Ná„n2Á…¡hÈ!# ¢ wþPÌJ,%žX‹-ºìÒË‹0 ƒ3&SãÍ8#M V°Üc6Anó‘H’cNK¦ã¤;ôPIe>WP@[Ôe—ù>@MæDfb4šj~t›n–tRqιRu”§MNìÙ§NôôS „•”¢Mñ”TŽBšU¥\Q Ä¥bdjh­ÅV nÅ%*©üp—^ªö¬„Ù kbŠÙŠk®’UFYf¿;,±Ækš ž³¯¡à,´³1`nÔöö[×—mÆ!×msÏunÕÅ@nÚëxê–wž»@(½nPÿÞ¼ôÕ'Å}÷ê—o¾þÿñ+ˆ¿&² ƒORÉ_¢0†¢hXJÄNÜ ,Ó²ñ-ŒÈÉŠŒ1#G;â5`ö#™ ‰H5‡ ’tŽœ­ÃIkp‡<~6%¡ácý(–¶%.i€i_jH˜¤F¦2)MWÈ׺֯Éil-±SLòd€›¤­O~r[Pu”BŠnvcÔTU•6HjR}\àÊbN®-¡R]êb*½ôeU­rÕ`d…Ì1W›sŒd&ó9ЉnX£óLéH“d¡N5ÌZl\­hÍN7Ô2‚ír—-mõN9ÝêðÀEÃÒ–Ú¡Ž§IÖ²ôغ×Í&ZÒª oœâg[?U$tÂåHã!¯\æBêwš·T¦b2^òÊÞ}¤Š¯ªúG|„(å¿1°T®R}J˜&<Ñ0ùѲ~·ÆÖºKþþéB¿ü_Ȇ1W“¡ì˜ d™Ë˜ÙÌ=<0‚6« :.ˆA F‰ AÁÐ@Â,‘ð›a˜Vµržó…Q§Ø9ÚPNòtIvÈCæDŸ=b?E(C)µ5èAØZ®,Ô+›â¦W¸µL”¢£²hó²Q¿„q0–iEz+Îñ ¥)å âØR—Úq5Êj uŸ5›ÞÔiw{zD&2¨ÒidÌ Éì(o½I­$z˜:½ê¹g“œÔž½¾à½PÞW@ã#Ÿ)¶Õ®Fˆ}˜x% \VSœUD#r…‰̱þùoÂ2"êŠá /“ÃÜðð7Šâ$þý•I$æÙ`é´{ˆý‡–¸„¦-ıb’Hd­–N†ÄpÒìfË&“;õŸ{BòNFÛÏÒÎ ‰wÃU¨Bå*[JŠp¨¯8Q¸„¹Të­ä::Æàf®Ín>ir•+,ÒÕù¹ÈJMž›å,gÕ»žÖvÓ]ïnËÐÍY$y©óÈœ×ÑF¤ºØÕ®wÁëzòŠª'9 Êð]€”‡@Ð)áß‚UÂîSõ…2dàˆÑ/D«H+þô·¿^úÒEr%Ù0-|ᔥ¯ÖkÌœYìpH°MR¶Ïæ1%W©h.ö&8Q8NˆØX²ISÖÖyY8-žó$·=Ñ}äuóþsÉÿ4"¢e¼Y剮}-–ÅBÅ,p™¶^¾m·Ø¸1§ÊÌ®®š…{Æ4÷ÍȳœîÜ;Ç”º°±®³hàì”о;ô·=ÔF£Ü;êeïó(íÔ§ÒK{ôå§ÃwÕC$‚¿©T¥Áì¾÷ÅR–­>º-)f±\2¸éPX„áW®6ÂÑ3V¶áÂ,Ø\/öofAvdJdo¶ÙõqØÄ–Ð á´¶ ³ÝÂŠà˜²ÞÖNo‚Y@F':t'8pnF¦¡Õ6>1DþTDsË¢D«Uo ue %[×)‡“8Z¤[]„*‘39”+³rph”p çFÀÒp¤W:þww¤,Z€zÖÕg´!;W-ƒDHÞe‡Ä-â%<#7.äI)iëâ<“6=ð¢IòÁòµiÞó=Ÿ†sò/Zå_ÿõs©æJœKÐ×!µd?÷³`Lç`æ?/â}´k$~w5 YÇ@Á63]÷WKX;ãDXö0Ûm7ðbkÇX×FNÚvcq—NkÂNmR6¤YAF6fSd{ZAô6¤Õd¦U7ÈD•P]¡YÖxW[X”Eºå8E‚‘ƒyU9)Èfi¤F»â9nôFÌu]4xzz´gª·ƒ7U;½a;¸3hßåS¿<³G<ŠÆh&WT¸Ç<ìeIþ¼G=Ö_U|T>ø%j r>É—>^tÍ7`BV³ä!HW1±¦†(ÒV,WÀ$23RL(3~+ókx˜‡Ã¦~džlÔ3'&g×bö§4ø§ˆûÚ¶m“Å(€X€9ÔY÷´€ ¸n£EDrPoõ(¬EQ´xS¤oûf[ fpd†y™Wp!5\#Å‚¼˜RËÅ\Á8ƒªszÍÂgwSÖzWHßõq‰$rÒQ^¶w{èi»çrí/P¥iùAsý¡/åX \¸sÓ ]µ>­4` #K³dtk“1úÃ1N÷1ûHa%c2Æ„@É”uÌ„~ÃÖWGòþu#vÖ4v(6ˆ+vXXrˆjcú·ˆn׈pw9‰íÔ&ádyWn{Çwêæ€@xq3Š2PŒbxM„PЇe©¸e´Q‚ÿ‹E‚_F'H›gF#•‹Çz¿"gt6”w†G2•z:h„S׌ºóŒ…^ˆFµg{X™•Må—_2w`‰…jd¹…ÇÇ_£Ž§†0â|Ïç0f…tr¹`ƒ}ýaÝÇ{© 72~¾–Wçç@i7£3Mò~c'%e÷l)mŠ‘ŠˆmÙpw59–‘àV‰ñd€0an øY}'’Ønrs(HPµD*UYo‰wo°É1ù)®øŠ±(‹eÆ›b„‚kÆ“+XRkô“¡ƒÀøpÂ(]gŒ4…q¹¡qÖ"AøqD(•DrD…è"+ÇZùðsÀ÷•5÷i;yaws-2.0.2/www/icons/small/ps.gif0000664000175000017500000000027012605311413013574 00000000000000GIF89aò999kkkŒŒŒÎÎÎçççÿÿÿ!ù!þby Martin.Kraemer@Mch.SNI.De,Â999kkkŒŒŒÎÎÎçççÿÿÿExºÜGÆ 0¢ ÚHú™H›-ÚF`MÀ)§òTY?¥î8-WÂöÈ@ˆ$‹v©ž)”kF ÒKc èz½ÊE;yaws-2.0.2/www/icons/small/patch.gif0000664000175000017500000000026612605311413014256 00000000000000GIF89aò999kkkŒŒŒÎÎÎçççÿÿÿ!ù!þby Martin.Kraemer@Mch.SNI.De,Â999kkkŒŒŒÎÎÎçççÿÿÿChºÜ6%Š2c Ú8º™5U¶hÛ@€ ºŠ© A½ÉÏûâŽÂ¶:È ¨!]„€ÓjRS•&•—ÆÊ  ;yaws-2.0.2/www/icons/small/image2.gif0000664000175000017500000000021212605311413014312 00000000000000GIF89a¢ÿÿÿÿÀÀÀÿRR{!{µŒŒ”RRZ!ù,OºÜ¾å@«Š®ZŠ™¦ œuÆQžB ¤w¶FQÕ °N-­ø…§X"‘Ê¡Gt@iÄÂf™¡Š÷[úhÀ–zÍL;yaws-2.0.2/www/icons/small/transfer.gif0000664000175000017500000000017412605311413015001 00000000000000GIF89a¢ÿÿÿÿkkkœœœÀÀÀï„„ïZZk!ù,A8ºÜ.‚)b›Ô®9&Ô^•…)B@Z…ÑETÜDNÜ5Ãÿ@Fàf(oŸÅP†¡%…̉áyi T+‘«H;yaws-2.0.2/www/icons/small/key.gif0000664000175000017500000000027312605311413013745 00000000000000GIF89aò999kkkŒŒŒÎÎÎçççÿÿÿ!ù!þby Martin.Kraemer@Mch.SNI.De,Â999kkkŒŒŒÎÎÎçççÿÿÿHxºÜG¦ˆYŒ5‚Ák‰?ƒv—-Ga l(§’œU?y¾;Š–«a %C`É0‰È‚óM ¤ƒéZÝ2“°¸¹H;yaws-2.0.2/www/icons/small/blank.gif0000664000175000017500000000006712605311413014245 00000000000000GIF89a€ÿÀÀÀ!ù,„©Ëí£œ´Ú‹³>;yaws-2.0.2/www/icons/small/image.gif0000664000175000017500000000017612605311413014241 00000000000000GIF89a¢ÿÿÿÿkkkŒŒŒÀÀÀïZZ„c1ïÖ9!ù,C8ºÜÎå<' ‘s•ˆó(Æ!xÃal¤ œ…¼o#LJÍ ”0žm@«{ßÑ–Tîz…€Tp.œË…@Êí¶ ;yaws-2.0.2/www/icons/small/binary.gif0000664000175000017500000000020612605311413014435 00000000000000GIF89a¢ÿÿÿÿ999kkkŒŒŒÀÀÀÎÎÎççç!ù,KHºÜ¾ã@k1±ÍJ'Ö\WD¦la ÌDF!¸o ÀƒpS†`ë`Å·˜ä µ¡í›)‹7ŒB<í‚;ªí˜ÔBCœª",—Y‹;yaws-2.0.2/www/icons/small/generic3.gif0000664000175000017500000000016112605311413014650 00000000000000GIF89a¢ÿkkkÀÀÀïZZkJ!ù,6ºÜ!0BàÂðÒvqßK'‰ …ADJ0"¦²§´†q4ÀµpÓù®´'Ÿ©‡« `Àl:gŠ;yaws-2.0.2/www/icons/small/burst.gif0000664000175000017500000000020012605311413014302 00000000000000GIF89a¢ÿÀÀÀ)!ZJÿç9œœ¥JJR!ù,EºÜþ0¢‘DhÁ0C”R,)¾Ú¸oýUa­ K¦×‚“ê÷2lQØ[éfLÆ,)*¢ +Çt‘P)G;yaws-2.0.2/www/icons/small/forward.gif0000664000175000017500000000017512605311413014622 00000000000000GIF89a¢ÿ999kkkŒŒŒÀÀÀÎÎÎ!ù,B8º´þ+XV…»†DÐe$ˆã÷ʼn–C³E‘8Xu_HÛÌGì"ÅâQqI ‘²‚›—›˜. r$;yaws-2.0.2/www/icons/small/compressed.gif0000664000175000017500000000020012605311413015307 00000000000000GIF89a¢ÿÿÿÿkkkœœœÀÀÀïZZkJ!ù,E8ºÜ.‚)b›Ô®9&Ô^•…)BÉ|U}JAtí #íDàº#Ì-v‚Ö x$z™Qa€@ƒ¤¦Šˆ¾]E;yaws-2.0.2/www/icons/small/sound.gif0000664000175000017500000000020212605311413014275 00000000000000GIF89a¢ÿÿÿÿsssÀÀÀÖœœ÷­9JJ!ù,G(ºÜþp1‰Â[ï;ÀD ¤ ` W«œ@ŸDPo Ïv °Í—c„z7Éa© °,ÐF`³•Ó ¡AQ¢˜°X;yaws-2.0.2/www/icons/small/back.gif0000664000175000017500000000020112605311413014044 00000000000000GIF89a¢ÿ!!!111ZZZ„„„ŒŒŒÀÀÀ!ù,FXºÜ ÀI`L”‹V‹‹Ð tÄf]Qn(i¶Ã ÈÊZD,­˜ž€00ZLƒ¡Ða"* Ѱ·°„EÇq3ÈJ`p#;yaws-2.0.2/www/icons/small/continued.gif0000664000175000017500000000016212605311413015142 00000000000000GIF89a¢ÿÿÿÿ999kkkŒŒŒÀÀÀÎÎÎççç!ù,7HºÜþ0ÊIY+„5¶ ÅEà ]ˆ±† ¥i¾åá–bpˆƒÃÓù-HÇ“ÂTi:ŸÐG;yaws-2.0.2/www/icons/small/generic2.gif0000664000175000017500000000017712605311413014656 00000000000000GIF89a¢ÿÿÿÿkkkœœœÀÀÀïZZkJ!ù,D8*¢þORT€€YÀ ¦qžwA#å9a¶©@QÕ“vš…¾¸œ.’ï·ú€ŠÛhã-‘窜aGH€V0l¿È;yaws-2.0.2/www/icons/small/README.txt0000664000175000017500000000045412605311413014165 00000000000000 These icons are provided as an alternative to the standard Apache icon graphics. All graphics in this directory, with the exception of rainbow.gif, are 16x16 pixels in size, rather than the 20x22 dimension icons which are the normal defaults for Apache and are in the parent directory of this one. yaws-2.0.2/www/icons/small/index.gif0000664000175000017500000000022112605311413014255 00000000000000GIF89a¢ÿÿÿÿ!!!ZZZŒŒŒÀÀÀ9B9”Þ÷!ù,VHºÜ¾ã@«¯Z›¦@`ÌGEqx¦Hìpk—B`Db ‰°3 r©BgX< ƒhT Ñ@Ê)X±”Û‚¢-¼Ò¸•n ¦‚¸<ÇH;yaws-2.0.2/www/icons/small/binhex.gif0000664000175000017500000000020312605311413014423 00000000000000GIF89a¢ÿÿÿÿ999kkkŒŒŒÀÀÀÎÎÎççç!ù,HHºÜ¾ã@k1±•À9˜˜FVQ™²u$À2S%+“½,;»Ik·êŒXÝ‚ƒß “{áÄmh˜ÍÚ­uÔOÓ[?‚>28‡ˆV ;yaws-2.0.2/www/icons/pie8.gif0000664000175000017500000000025512605311413012712 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,,Œ©Ëí£4¢Öhómº³*à˜Œáa’Tê­l†¾°+ Hmßµø~©cÂÌ;yaws-2.0.2/www/icons/ball.red.gif0000664000175000017500000000031512605311413013525 00000000000000GIF89aÂÿÿÿÿ™™ÿ33Ìÿÿf!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,@8ºÜþ0ÊI«]%—[‚Õ aÔdy¦O!”%aÃN7›/ÞÈ<ÊÇNCbQˆBU IeLs©Z¯Ø¬V‘;yaws-2.0.2/www/icons/portal.gif0000664000175000017500000000037612605311413013352 00000000000000GIF89aÂÿÿÿÿÌ3ÌÿÿÌÌÌÌ™3™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,qhº¼òP@«&¾i;Ï×U"¸‘rAeᾇÏ'eG®ïy Ü‚npxá|7B@x `H³y¨%$\Nè¤\[¼îó «^2Ö¦=[Õà-õØïâo…·£¯G€z€pƒ„7FŠF2|: ;yaws-2.0.2/www/icons/sphere2.gif0000664000175000017500000000041012605311413013406 00000000000000GIF89aÂÿÿÿÿ™™ÿ33Ìÿÿ™™™f333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,{hº¼óp@«&¾i;Ï×U"¸×‰èa¸ð‰RGmru|OàË!@|< h…£OI#6PiRv8…°öÇý>³c* {G¥rpý,@ßGŠ|éŽF {Bxyj:6€‚3#Œ‹JH”=/7™š@ ;yaws-2.0.2/www/icons/folder.gif0000664000175000017500000000034112605311413013314 00000000000000GIF89aÂÿÿÿÿÌ™Ìÿÿ™f3333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,T(ºÜþ0ÊIY¹øÎºïEÄ}d¦)Å@zj‰C,Ç+ŽõWž<œì IEáqg<²‚N"4ÚIRaV˜VÅÝÂx‚Ôl<&€Ãæ´zÍ#,LðŒ;;yaws-2.0.2/www/icons/world2.gif0000664000175000017500000000040512605311413013253 00000000000000GIF89aÂÿÿÿÌÿÿÌÌÌ™™™™3f3!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,xºÜî&Ê×"¹8Ò(ˆø¨1ÆbXWd×…¨·.åëzx7ÌAiÚ°OaÀªÝN Á®°2þ€:&Ñ|]†C 0ä wÓTrüÍú>§xYüq¯Ì8«—FøòœnËã×{=~q_K<4…„L#~x=’“— ;yaws-2.0.2/www/icons/ball.gray.gif0000664000175000017500000000035112605311413013715 00000000000000GIF89aãÿÿÿÌÿÿÌÌÌ»»»™™™ˆˆˆfffUUU333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,D0ÈI«½8ëÍ»ŸI˜| a#WBaiVÀàH|•&ñ"9 Ï÷ È_NgI ¸%³ &‚*éT&úx¿à°x,‰;yaws-2.0.2/www/icons/compressed.gif0000664000175000017500000000201612605311413014206 00000000000000GIF89açÿÿÿÿÿÌÿÿ™ÿÿfÿÿ3ÿÿÿÌÿÿÌÌÿÌ™ÿÌfÿÌ3ÿÌÿ™ÿÿ™Ìÿ™™ÿ™fÿ™3ÿ™ÿfÿÿfÌÿf™ÿffÿf3ÿfÿ3ÿÿ3Ìÿ3™ÿ3fÿ33ÿ3ÿÿÿÌÿ™ÿfÿ3ÿÌÿÿÌÿÌÌÿ™ÌÿfÌÿ3ÌÿÌÌÿÌÌÌÌÌ™ÌÌfÌÌ3ÌÌÌ™ÿÌ™ÌÌ™™Ì™fÌ™3Ì™ÌfÿÌfÌÌf™ÌffÌf3ÌfÌ3ÿÌ3ÌÌ3™Ì3fÌ33Ì3ÌÿÌÌÌ™ÌfÌ3Ì™ÿÿ™ÿÌ™ÿ™™ÿf™ÿ3™ÿ™Ìÿ™Ì̙̙™Ìf™Ì3™Ì™™ÿ™™Ì™™™™™f™™3™™™fÿ™fÌ™f™™ff™f3™f™3ÿ™3Ì™3™™3f™33™3™ÿ™Ì™™™f™3™fÿÿfÿÌfÿ™fÿffÿ3fÿfÌÿfÌÌfÌ™fÌffÌ3fÌf™ÿf™Ìf™™f™ff™3f™ffÿffÌff™fffff3fff3ÿf3Ìf3™f3ff33f3fÿfÌf™fff3f3ÿÿ3ÿÌ3ÿ™3ÿf3ÿ33ÿ3Ìÿ3ÌÌ3Ì™3Ìf3Ì33Ì3™ÿ3™Ì3™™3™f3™33™3fÿ3fÌ3f™3ff3f33f33ÿ33Ì33™33f333333ÿ3Ì3™3f333ÿÿÿÌÿ™ÿfÿ3ÿÌÿÌÌÌ™ÌfÌ3Ì™ÿ™Ì™™™f™3™fÿfÌf™fff3f3ÿ3Ì3™3f333ÿÌ™f3îÝ»ªˆwUD"îÝ»ªˆwUD"îÝ»ªˆwUD"îîîÝÝÝ»»»ªªªˆˆˆwwwUUUDDD"""!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù$,™I$Áª`ÁdCV #lÈСĄ+Z¼(0cCŠ'øÇФIŽÿ©\ùåGVbZi™ð‡Ž/aƤÉá‘@›75¾œI‚CÏŸF9ý83©O@ælh%éQ¨V9LÍú4jÏ©^»: 3ªØžK©þ*ÖgZ˜-mv}ú–(Ô§ëÒ”¨%+™2K†$Á’¥Â€;yaws-2.0.2/www/icons/back.gif0000664000175000017500000000033012605311413012737 00000000000000GIF89aÂÿÿÿÌÿÿ™™™fff333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,KºÜþ#òj3S»¢ÎÜõiœ7Nv‚t7*EnXm/û’ë5FPñêxƤ‘¦l(N§ ÚŒÀ¨:‚@ÕV’ÞÐUüè‘Ï‹;yaws-2.0.2/www/icons/pie2.gif0000664000175000017500000000030612605311413012701 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,EŒ©Ëí£4¢ÖX°· ­qò›(fˆ¦Hi¶.µ²íÇ2^Ÿ7ÝëÍrAÐ,@(—Ê#’ e:ŸQ)#¹œ¾ˆ#‡ˆQ;yaws-2.0.2/www/icons/world1.gif0000664000175000017500000000034412605311413013254 00000000000000GIF89a¡ÿÿÿÌÿÿ™3!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,cŒ©:훚˜´ÁØš[4LEeÂfæXžG¸j²*£A(ÆÜŽÂô¸3|9L#ª„"$¬ÙYvœ¥ ”‡Û°rSWvÉ$Ù,mtj»)Á´šVºo¾ððB ǃ¸P;yaws-2.0.2/www/icons/pdf.gif0000664000175000017500000000037112605311413012615 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,l8º¼ñ0 @«#¾IºïÀjÜç…U‰ØhºV&L w¾UÂ'¼¦eH{»š«h$$•D¤äeYòœS%l(ôL?.–EŒŽ&€zÝEÖìódU·ç¶-üïïå~]G…†F8ZZ ;yaws-2.0.2/www/icons/continued.gif0000664000175000017500000000032612605311413014034 00000000000000GIF89aÂÿÿÿÌÿÿ™™™fff333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,IºÜþ0ÊI«½Ø•ÒvçJ!` ’Ëɉ€²î*´$;Êî;ß§0È£Ÿiä+ ƒ!pL™H%ô©8R§ËjvAØj3à°xL.+;yaws-2.0.2/www/icons/pie0.gif0000664000175000017500000000027412605311413012703 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,;Œ©Ëí£4¢ÖXÖ·‰ r̆‚B–f’ªÛy´îÏ%È6®Ï¼½ª8ʈ=‘GÖyX¢‰;yaws-2.0.2/www/icons/index.gif0000664000175000017500000000041412605311413013151 00000000000000GIF89aÂÿÿÿÌÿÿ™™™fÌÿ333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,Hº¼ñ0@«$¾i;Ï×U"¸×‰hA¸ð‰REmr%ì‚ÎãÝËFè~2K0^Æ#ðChZ €VyR2µVåkX›(›€ëÀÕpIÕÖïg–Õ7¢VÏn§EMOrZR9„DQ‡A†G<Ž9‘”Œ s˜˜/yy ;yaws-2.0.2/www/icons/sound1.gif0000664000175000017500000000037012605311413013254 00000000000000GIF89aÂÿÿÿÿ33ÌÿÿÌÌÌ™™™f333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,k(ºÜþ06ÃBêaU±q …Àh~ šržwi4Ü[×AHü¶ÛkwṄ O°4‘8fqz„*§Ò*ò*Í ßoÒÔœÑCT‡Þ´:3Mä*6$>}J{v,{ „‰Š ;yaws-2.0.2/www/icons/comp.gray.gif0000664000175000017500000000036612605311413013747 00000000000000GIF89aÂÿÿÿÌÿÿ™™™fÌÿ333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,iºÜþ0ÊXª½À»™³aHˆ 7¬+a¢˺ÅÙŒòüÞ`ÞîŒaH›Ï§Æ ’0ÄA@­Z¯„дÈíj¯`kV1-ÌÏŠ`¬0+?çPÀ½]Û·€ø\¨ûïy5iƒ']‡\ ;yaws-2.0.2/www/icons/sphere1.gif0000664000175000017500000000043512605311413013414 00000000000000GIF89aãÿÿÿÿ™™ÿ33ÌÿÿÌÌÌ™™™f333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,xpÈI«½8ë:ڌŠ@ †™‰Aª²î…ªjìõtnECɸw-T2VTʬ–Wh«5¥šÀawêE_=åî™}¬—ÛL¡~$°çy{‚~VSz‰…†_qŽw€Žm?|–H5jš›&;yaws-2.0.2/www/icons/pie3.gif0000664000175000017500000000027712605311413012711 00000000000000GIF89a¡ÿÿÿÌÿÿ!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,>Œ©Ëí£4¢ÖX°· ­qò›(fˆ¦Hi¶.µ²íÇ2^Ÿ7ÝÛƒ¨WÏ6“Ê“wœ-2: ‡Q;yaws-2.0.2/www/icons/tex.gif0000664000175000017500000000037312605311413012646 00000000000000GIF89aÂÿÿÿÌÿÿ™™™333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,n8º¼ñ0 @«#¾i)!—EÓgša5nÀy¦*Äu_;÷Í ¦`¹–«y–’x$$QD RRùø¢E'ËÔ–p”¨3ý»¬ê8Zn×€xû#ªÅïí»~/÷òÿ}i€{eG‡ˆF:oZ ;yaws-2.0.2/www/icons/binhex.gif0000664000175000017500000000036612605311413013325 00000000000000GIF89aÂÿÿÿÌÿÿ™™™fff333!þNThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995!ù,iHº¼ñ0@«$¾YºïÀjÜç…U‰˜^+`žQß›<º™[@Š`((äŠ&…h”ôLÁbޤ.›˜]«|”@© s;"›µ".Ͷ¿ÖÚ<ÕÒhŠî,—ÛD‚ƒC6;ˆM ;yaws-2.0.2/www/urandom_from_pid.yaws0000664000175000017500000000221012605311413014465 00000000000000 out(A) -> %% Create a random number {_A1, A2, A3} = now(), random:seed(erlang:phash(node(), 100000), erlang:phash(A2, A3), A3), Sz = random:uniform(100000), Pid = spawn(fun() -> %% Read random junk S="dd if=/dev/urandom count=1 bs=" ++ integer_to_list(Sz) ++ " 2>/dev/null", P = open_port({spawn, S}, [binary,stream, eof]), rec_loop(A#arg.clisock, P) end), [{header, {content_length, Sz}}, {streamcontent_from_pid, "application/octet-stream", Pid}]. rec_loop(Sock, P) -> receive {discard, YawsPid} -> yaws_api:stream_process_end(Sock, YawsPid); {ok, YawsPid} -> rec_loop(Sock, YawsPid, P) end, port_close(P), exit(normal). rec_loop(Sock, YawsPid, P) -> receive {P, {data, BinData}} -> yaws_api:stream_process_deliver(Sock, BinData), rec_loop(Sock, YawsPid, P); {P, eof} -> yaws_api:stream_process_end(Sock, YawsPid) end. yaws-2.0.2/www/TAB.inc0000664000175000017500000000640312605311413011345 00000000000000 Yaws yaws-2.0.2/www/internals.yaws0000664000175000017500000002574212605311413013157 00000000000000 out(A) -> {ssi, "TAB.inc", "%%",[{"internals", "choosen"}]}.

    Internals

    Introduction

    I'll try to describe some of the internal workings of Yaws in this page. The page is thus mostly interesting for people interested in either hacking Yaws or simply wanting to get a better understanding.

    I'll describe how Yaws pages get compiled, the process structure and other things which can make it easier to understand the code. This page is ment to be read by programmers that wish to either work on Yaws or just get a better understanding.

    JIT Compiling a .yaws page

    When the client GETs a a page that has a .yaws suffix. The Yaws server will read that page from the hard disk and divide it in parts that consist of HTML code and Erlang code. Each chunk of Erlang code will be compiled into a module. The chunk of Erlang code must contain a function out/1 If it doesn't the Yaws server will insert a proper error message into the generated HTML output.

    When the Yaws server ships a .yaws page it will process it chunk by chunk through the .yaws file. If it is HTML code, the server will ship that as is, whereas if it is Erlang code, the Yaws server will invoke the out/1 function in that code and insert the output of that out/1 function into the stream of HTML that is being shipped to the client.

    Yaws will cache the result of the compilation and the next time a client requests the same .yaws page Yaws will be able to invoke the already compiled modules directly.

    This is best explained by an example:

    Say that a file consists of 400 bytes, we have "foo.yaws" and it looks like:

    When a client request the file "foo.yaws", the webserver will look in its cache for the file, (more on that later). For the sake of argument, we assume the file is not in the cache.

    The file will be processes by the code in yaws_compile.erl and the result will be a structure that looks like:

    [CodeSpec] CodeSpec = Data | Code | Error Data = {data, NumChars} Code = {mod, LineNo, YawsFile, NumSkipChars, Mod, Func} Err = {error, NumSkipChars, E}

    In the particular case of our "foo.yaws" file above, the JIT compiler will return:

    [{mod, 1, "/foo.yaws", 100, m1, out}, {data, 200}, {mod, 30, "/foo.yaws", 100, m2, out} ]

    This structure gets stored in the cache and will continue to be associated to the file "foo.yaws".

    When the server "ships" a .yaws page, it needs the CodeSpec structure to do it. If the structure is not in the cache, the page gets JIT compiled and inserted into the cache.

    To ship the above CodeSpec structure, the server performs the following steps:

    1. Create the Arg structure which is a #arg{} record, this structure is wellknown to all yaws programmers since it's the main mechanism to pass data from the server to the .yaws page.
    2. Item (1) Invoke m1:out(Arg)
    3. Look at the return value from m1:out(Arg) and perform whatever is requested. This typically involves generating some dynamic ehtml code, generate headers or whatever.
    4. Finally jump ahead 100 bytes in the file as a result of processing the first CodeSpec item.
    5. Item (2) Next CodeSpec is just plain data from the file, thus we read 200 bytes from the file (or rather from the cache since the data will be there) and ship to the client.
    6. Item (3) Yet another {mod structure which is handled the same way as Item (1) above except that the erlang module is m2 instead of m1

    Another thing that is worth mentioning is that yaws will not ship (write on the socket) data until all content is generated. This is questionable and different from what i.e. PHP does. This makes it possible to generate headers after content has been generated.

    Process structure

    Before describing the process structure, I need to describe the two most important datastructures in Yaws. The #gconf{} and the #sconf{} records.

    Note: To retrieve information from these records, yaws:gconf_*/1 and yaws:sconf_*/1 (e.g. yaws:gconf_id/1 or yaws:sconf_docroot/1) should be used in preference to a direct access to reduce the dependence of your code on it.

    The #gconf{} record

    This record is used to hold all global state, i.e. state and configuration data which is valid for all Virtual servers. The record looks like:

    %%global conf record(gconf,{ yaws_dir, % topdir of Yaws installation trace, % false | {true,http} | {true,traffic} flags = ?GC_DEF, % boolean flags logdir, ebin_dir = [], runmods = [], % runmods for entire server keepalive_timeout = 30000, keepalive_maxuses = nolimit, % nolimit or non negative integer max_num_cached_files = 400, max_num_cached_bytes = 1000000, % 1 MEG max_size_cached_file = 8000, max_connections = nolimit, % max number of TCP connections %% Override default connection handler processes spawn options for %% performance/memory tuning. %% [] | [{fullsweep_after,Number}, {min_heap_size, Size}] %% other options such as monitor, link are ignored. process_options = [], large_file_chunk_size = 10240, mnesia_dir = [], log_wrap_size = 10000000, % wrap logs after 10M cache_refresh_secs = 30, % seconds (auto zero when debug) include_dir = [], % list of inc dirs for .yaws files phpexe = "/usr/bin/php-cgi", % cgi capable php executable yaws, % server string id = "default", % string identifying this instance of yaws enable_soap = false, % start yaws_soap_srv iff true %% a list of %% {{Mod, Func}, WsdlFile, Prefix} | {{Mod, Func}, WsdlFile} %% automatically setup in yaws_soap_srv init. soap_srv_mods = [], ysession_mod = yaws_session_server, % storage module for ysession acceptor_pool_size = 8, % size of acceptor proc pool mime_types_info % undefined | #mime_types_info{} }).

    The structure is derived from the /etc/yaws/yaws.conf file and is passed around all through the functions in the server.

    The #sconf{} record

    The next important datastructure is the #sconf{} record. It is used to describe a single virtual server.

    Each:

    .....

    In the /etc/yaws/yaws.conf file corresponds to one #sconf{} record. We have:

    %% server conf -record(sconf, { port = 8000, % which port is this server listening to flags = ?SC_DEF, redirect_map=[], % a list of % {Prefix, #url{}, append|noappend} % #url{} can be partially populated rhost, % forced redirect host (+ optional port) rmethod, % forced redirect method docroot, % path to the docs xtra_docroots = [], % if we have additional pseudo docroots listen = [{127,0,0,1}], % bind to this IP, {0,0,0,0} is possible servername = "localhost", % servername is what Host: header is yaws, % server string for this vhost ets, % local store for this server ssl, % undefined | #ssl{} authdirs = [], % [{docroot, [#auth{}]}] partial_post_size = 10240, %% An item in the appmods list can be either of the %% following, this is all due to backwards compat issues. %% 1. an atom - this is the equivalent to {atom, atom} %% 2 . A two tuple {Path, Mod} %% 3 A three tuple {Path, Mod, [ExcludeDir ....]} appmods = [], expires = [], errormod_401 = yaws_outmod, % the default 401 error module errormod_404 = yaws_outmod, % the default 404 error module errormod_crash = yaws_outmod, % use the same module for crashes arg_rewrite_mod = yaws, logger_mod = yaws_log, % access/auth logging module opaque = [], % useful in embedded mode start_mod, % user provided module to be started allowed_scripts = [yaws,php,cgi,fcgi], tilde_allowed_scripts = [], index_files = ["index.yaws", "index.html", "index.php"], revproxy = [], soptions = [], extra_cgi_vars = [], stats, % raw traffic statistics fcgi_app_server, % FastCGI application server {host,port} php_handler = {cgi, "/usr/bin/php-cgi"}, shaper, deflate_options, % undefined | #deflate{} mime_types_info, % undefined | #mime_types_info{} % if undefined, global config is used dispatch_mod % custom dispatch module }).

    Both of these two structures are defined in "yaws.hrl"

    Now we're ready to describe the process structure. We have:

    Thus, all the different "servers" defined in the configuration file are clumped together in groups. For HTTP (i.e. not HTTPS) servers there can be multiple virtual servers per IP address. Each group is defined by the pair {IpAddr, Port} and they all need to have different server names.

    The client will send the server name in the "Host:" header and that header is used to pick a #sconf{} record out of the list of virtual servers for a specific {Ip,Port} pair.

    SSL servers are different, we cannot read the headers before we decide which virtual server to choose because the certificate is connected to a server name. Thus, there can only be one HTTPS server per {Ip,Port} pair.

    out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/simple_ex3.yaws0000664000175000017500000000017112605311413013215 00000000000000

    Yesssssss

    out(Arg) -> {ehtml, [{h2, [{class, "foo"}], "Hello yet again"}]}. yaws-2.0.2/www/contact.yaws0000664000175000017500000000122012605311413012574 00000000000000 out(A) -> {ssi, "TAB.inc","%%",[{"contact", "choosen"}]}.

    Contact

    There is a mailinglist which is used to discuss yaws. The list is called erlyaws-list and it is run by Sourceforge.

    The URL to the list is: https://lists.sourceforge.net/lists/listinfo/erlyaws-list

    It is also possible to contact:

        klacke @ hyber . org
        Cell: +46 0702097763
      
    out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/stream.yaws0000664000175000017500000001260012605311413012440 00000000000000 box(Str) -> {'div',[{class,"box"}], {pre,[],yaws_api:htmlize(Str)}}. tbox(T) -> box(lists:flatten(io_lib:format("~p",[T]))). ssi(File) -> {'div',[{class,"box"}], {pre,[], {ssi, File,[],[]}}}. out(A) -> [{ssi, "TAB.inc", "%%",[{"stream", "choosen"}]}, {ehtml, {'div',[{id, "entry"}], [{h1, [], "Streaming data to the client"}, {p, [], "Sometimes we want to stream data to the client. Maybe we don't know or cannot compute the size of the data. Regardless of the reason, we do not want to keep all data in memory until it's shipped to the client. We want to use chunked encodings, and simply send data in chunks to the client. This is performed in steps. First the out/1 return value:"}, box(" {streamcontent, MimeType, FirstChunk}"), {p,[], ["Is returned from the out/1 function" " This makes the erlang process within yaws processing that particular page go into a receive loop, waiting for more data. Somehow, another process in the erlang system must then deliver data to the waiting/receiving erlang process. There are two asynchronous API functions that can be used to deliver that data."]}, box("yaws_api:stream_chunk_deliver(YawsPid, Data)"), {p, [], "and"}, box("yaws_api:stream_chunk_end(YawsPid)"), {p, [], "The YawsPid argument is the process identifier of the original yaws process processing the page, i.e. self(), in the .yaws file."}, {p, [],"Maybe this gets clear with a programming example, let's use a process reading a random number of bytes from /dev/urandom as the source of the data"}, ssi("urandom.yaws"), {p, [], ["The above slightly bizarre code can be executed ", {a, [{href, "urandom.yaws"}], "here"}, ". The code creates a process which reads a random amount of bytes from /dev/urandom and sends them to the client, piece by piece. "]}, {p,[], "There is also a version of the API that delivers the data in a blocking fashion. Whenever the producer of the stream is faster than the consumer, that is the WWW client, we must use a synchronous version of the code. The api function is called:"}, box("yaws_api:stream_chunk_deliver_blocking(YawsPid, Data)"), {p,[], "For applications that want to avoid buffering data in memory but do not want chunked transfer, or for applications that employ long-polling (Comet) techniques, another streamcontent variant lets the application send data directly on the client socket. Such applications should first return the following from their out/1 function:"}, box(" {streamcontent_from_pid, MimeType, Pid}"), {p,[], "where the Pid argument is the pid of the application process that will send the data, and MimeType is the MIME type of the data to be sent. When yaws is ready for Pid, it sends one of the following messages to it:"}, {ul,[], [{li,[]," {ok, YawsPid} indicates to Pid that it can send data over the socket, which is available as Arg#arg.clisock. YawsPid will be used later to tell yaws that Pid has finished streaming."}, {li,[]," {discard, YawsPid} indicates to Pid that it should avoid sending data to the socket. This is needed when the client invokes an HTTP request such as HEAD that has no response body."}]}, {p,[],"Pid can send data on the socket by calling:"}, box(" yaws_api:stream_process_deliver(Socket, IoList)"), {p,[],"where IoList is the data to be sent. For chunked transfer, Pid must call:"}, box(" yaws_api:stream_process_deliver_chunk(Socket, IoList)"), {p,[],"which tells yaws to use HTTP chunked transfer to send IoList. Applications using chunked transfer in this manner must always remember to end their data transfer by calling:"}, box(" yaws_api:stream_process_deliver_final_chunk(Socket, IoList)"), {p,[],"where IoList is an iolist of size 0 or more. This creates the final HTTP chunk that the client uses to detect the end of the transfer."}, {p,[],"When Pid finishes sending data, or when it receives a {discard, YawsPid} message, it must call:"}, box(" yaws_api:stream_process_end(Socket, YawsPid)"), {p,[],"This informs yaws that Pid is finished with the socket and will no longer use it directly."}, box(" yaws_api:stream_process_end(closed, YawsPid)"), {p,[],"This informs yaws that Pid has not only finished with the socket, but has also closed it. Yaws will not attempt to use the socket anymore after the application calls this function."}, {p,[],"Applications using streamcontent_from_pid should be sure to set a Content-Length header in their out/1 return value if they want to avoid chunked transfer encoding for their return value. Yaws automatically sets the HTTP Transfer-Encoding header to chunked if it doesn't detect a Content-Length header. Another alternative is to return the {header, {transfer_encoding, erase}} header from out/1 in order to disable chunked encoding."}, {p,[],"Here's an example of using streamcontent_from_pid:"}, ssi("urandom_from_pid.yaws"), {p, [], ["The above code can be executed ", {a, [{href, "urandom_from_pid.yaws"}], "Here"}, ". The code creates a process which reads a random amount of bytes from /dev/urandom and sends them to the client via the socket. "]} ]}}, {ssi, "END2",[],[]} ]. yaws-2.0.2/www/simple_ex1.yaws0000664000175000017500000000005012605311413013207 00000000000000

    Hello world

    yaws-2.0.2/www/dynamic.yaws0000664000175000017500000001740412605311413012600 00000000000000 box(Str) -> {'div',[{class,"box"}], {pre, [], yaws_api:htmlize(Str)}}. tbox(T) -> box(lists:flatten(io_lib:format("~p",[T]))). ssi(File) -> {'div',[{class,"box"}], {pre,[], {ssi, File,[],[]}}}. out(A) -> [{ssi, "TAB.inc", "%%",[{"dynamic", "choosen"}]}, {ehtml, [{'div', [{id, "entry"}], [ {h1, [],"Generating Dynamic Content"}, {p,[], ["Yaws has very nice support for generating dynamic content on the fly. " "We use embedded erlang code to generate the content. The Erlang code " "is separated from the HTML code by ", {tt, [], "<erl>"}, " and ", {tt, [], "\</erl>"}, " markers. For example: "]}, box("

    Foobar

    \ out(Arg) -> {html, \"Funky Stuff\"}. \

    Baz

    "), {p,[], ["Is a very small example where we have a HTML document with embedded " "erlang code. A file which contains embedded erlang code must have the file " "suffix ", {tt, [], ".yaws"}]}, {br,[],[]}, {p, [], "The embedded erlang code can return the different values which will " " trigger the yaws webserver to do different things. We list some of the simple " " return values here: "}, {ul, [], [{li,[], [{p, [], [{tt,[],"{html, DeepCharOrBinaryList}"}, " Which will make the value of ", {tt, [],"DeepCharOrBinaryList"}, " be substituted into the HTML document."]}]}, {li,[], {p,[], [{tt,[],"{ehtml, ErlangTermStructure}"}]}}]}, {p, [], ["It is often more convenient to return " "erlang terms which are then transformed to HTML instead " "of returning plain HTML in string form using the ", {tt,[], "html"}, " tag "]}, {p,[], ["Using the ehtml return value, we can return deep structured " " erlang terms that correspond directly to HTML code. For example: "]}, box(" {table, [{bgcolor, \"tan\"}], {tr, [], [{td, [{width, \"70%\"}], {p, [{class, \"foo\"}], \"Hi there\"}}]}} "), {p, [], "Corresponds to the following HTML code: "}, box("

    Hi there

    "), {ul, [], [{li,[], {p,[], [{tt,[], "{header, Header}"}, " If a " , {tt, [], "header"}, " structure is returned, an additional header is inserted among the HTTP headers generated by yaws. " "This is used to insert for example Set-Cookie headers. The ", {tt,[], "Header"}, " variable must not be newline terminated."]}}, {li,[], {p,[], [{tt,[], "{allheaders, Header}"}, " If an ", {tt, [], "allheaders"}, " structure is returned, all previous headers that have been generated, including those " "default hedaers generated by yaws itself are erased, and replaced by " "the headers in ", {tt, [], "Headers"}, ". The variable ", {tt,[], "Headers"}, " must be a list of ", {tt, [], "{header, Str}"}, " tuples. The ", {tt, [], "Str"}, " must not be newline terminated. "]}}, {li,[], {p,[], [{tt, [], "{status, StatusCodeInt} "}, "Is used to force yaws to return a different status code than the " " default 200 code."]}}, {li,[], {p,[], [{tt, [], "ok"}, " Do nothing."]}}, {li,[], {p,[], [{tt, [], "{content, MimeType, Content} "}, "Sets the mime type, that is " "the Content-Type: header to be ", {tt, [], "MimeType"}, " The default value is of course \"text/html\", but applications that " "generate i.e wml or pdf, must set the Content-Type. " " A pdf generating application can for example return the " "tuple ", {tt, [], " {content, \"application/pdf\", PdfContentData} "}]}}, {li,[], {p,[], [{tt, [], "{redirect, URL} "}," a redirect is issued to the location in ", {tt, [], " URL "}]}}, {li,[], {p,[], [{tt, [], "{redirect_local, Path} "}," a redirect is issued to the local " "server using the same method (http or https) as the incoming request " " and the path part of the location header to the value in ", {tt, [], " Path "},"."]}}, {li,[], {p,[], [{tt, [], "{'EXIT', normal}"}," which will terminate the " " client connection in an uncontrolled way. "]}}, {li,[], {p,[], [{tt, [], "{ssi, File, Delimiter, Bindings}"}, " Using this construct, we can deep inside a ehtml structure, " " return (ssi) Server Side Include content from a file. " "This construct is further described in ", {a, [{href, "ssi.yaws"}], "ssi.yaws"}, "."]}} ]}, {p,[],["The embedded erlang code can also return a list of the " " above values. For example the following value "]}, box(" [{status, 303}, {allheaders, [{header, [\"Location: \",\"http://www.funky.org/\"]}, {header, [\"Set-Cookie: \",\"namn=ruler;\"]} ]}, {html,\" Redirected to funky.org \"} "), {p,[],"Can be returned if we want to issue a redirect and set a cookie " "at the same time."}, {p,[],["All possible return values from the out/1 function are documented in " "the man page for ", {a, [{href, "yman.yaws?page=yaws_api"}], ["", {tt, [], "yaws_api (5)"}]}]}, {p,[],"It can also be instructive to look at the actual source " "for the pages we are viewing at this very moment. Here are some of them"}, {ul, [], [ {li,[], [{p,[], [{a, [{href, "index.yaws"}], "The top page, index.yaws"}, " and then the ", {a, [{href, "code.yaws?file=/index.yaws"}], "corresponding source"}]}]}, {li,[], [{p,[], [{a, [{href, "dynamic.yaws"}], "This page, dynamic.yaws"}, " and then the ", {a, [{href, "code.yaws?file=/dynamic.yaws"}], "corresponding source"}]}]} ]}, {h2,[],"The argument "}, {p,[],["The ", {tt, [], "out/1"}," function is supplied with a record argument. The " "definition of that record is automatically included in the embedded erlang code " "and the record definition is: "]}, ssi("ssi/dynamic.2"), {p,[], "And some of the refered records are defined as:"}, ssi("ssi/dynamic.3"), {p, [], "Each chunk of erlang code will be compiled into a separate module. " "The module names are automatically generated. If we have functions inside the " "erlang chunks that we want to call from other chunks or modules, it is possible " " to explicitly name the modue that will be used as in: "}, box(" \ out(A) -> io:format('This is the foobar module',[]). func() -> i_am_exported_from_foobar. \") ]}]}].
    out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/END0000664000175000017500000000005712605311413010574 00000000000000
    yaws-2.0.2/www/cgi.yaws0000664000175000017500000000457612605311413011724 00000000000000 out(A) -> {ssi, "TAB.inc", "%%",[{"cgi", "choosen"}]}.

    Plain CGI and PHP

    Yaws supports plain CGI just fine. The two most common ways to run yaws cgi script is either as regular cgi scripts or as php scripts through the typical php-cgi binary. Yaws chooses how to ship a file based on file extension. Let's start with the php-cgi example. PHP files have the extension .php and if we enable php by indicating it in yaws.conf:

    php_exe_path = /usr/bin/php-cgi

    And then also ensure that we have enabled php processing for the individual server as in:

    port = 80 listen = 0.0.0.0 allowed_scripts = php yaws cgi ....

    Yaws will invoke the php-cgi binary and talk the CGI protocol to the binary.

    Another common situation is that we write our CGI scripts in e.g. python and use python libraries to speak the CGI protocol. The easiest way forward here is to rename the python scripts with the extension ".cgi" as in this example:

    We have the following python file called foo.cgi:

    #!/usr/bin/python import cgi print "Content-type: text/html\n\n" print "

    hi there

    "

    Since the file ends with the magic suffix ".cgi", Yaws will just invoke the file as an executable and speak CGI to it. Thus for this scheme to work we must also make the file executable.

    Yet another common scenario is when have a set of CGI files not ending with the ".cgi" file extension. We can put all the CGI files in a common directory and define an appmod as follows:

    out(Arg) -> yaws_cgi:call_cgi(Arg, lists:flatten(Arg#arg.fullpath)).

    and then configure the appmod appropriately in yaws.conf. The default yaws.conf file contains an entry.

    appmods =

    Thus if we put put any executable files in the "cgi-bin" directory under the docroot, Yaws will speak CGI to those executables.

    out(A) -> {ssi, "END2",[],[]}. yaws-2.0.2/www/todo.yaws0000664000175000017500000000175712605311413012125 00000000000000 out(A) -> yaws_api:ssi(A#arg.docroot, ["/HEAD", "/TOPTAB"]).

    TODO

    • Test suites !!!
    • Http client code/lib
    • Load and unload configs without disturbing existing sessions.
    • respect client side Cache-Control: no-cache
    • clusters, it would be fairly straightforward to build support for webfarms into yaws. Now it works ofcource with a normal loadbalancer and mnesia across a set of nodes, but we could migrate IPs and stuff as well.
    • TRACE, PUT, OPTIONS ......
    • more documentation in the www directory
    • redo the docs completely, docbook ??
    • more functions in yaws_api
    • lots of examples, mnesia examples.
    • do something cool, maybe a streaming audio app
    • shell access into the daemon .... no bad idea .. ?? Maybe using distributed erlang to do that.
    • HTTP trailer support (why ??)
    • webdav, lots of work.
    • content negotiation / language support
    out(A) -> yaws_api:ssi(A#arg.docroot, ["/END"]). yaws-2.0.2/www/haxe_intro.yaws0000664000175000017500000001055212605311413013311 00000000000000 box(Str) -> {'div',[{class,"box"}], {pre,[], yaws_api:htmlize(Str)}}. tbox(T) -> box(lists:flatten(io_lib:format("~p",[T]))). ssi(File) -> {'div',[{class,"box"}], {pre,[], {ssi, File,[],[]}}}. ss(A, File) -> {ok, B} = file:read_file( filename:join([A#arg.docroot, File])), box(binary_to_list(B)). out(A) -> [{ssi, "TAB.inc", "%%",[{"haxe_intro", "choosen"}]}, {ehtml, {'div', [{id, "entry"}], [{h1, [], "haXe remoting"}, {p, [], ["The yaws_rpc module has a haXe remoting adapter that enables " "Yaws to respond to respond to " "RPC requests from a client written in ", {a, [{href, "http://www.haxe.org"}], "haXe"}, ". haXe is a versatile open source language that compiles to " "Flash, Javascript and NekoVM. ", "For more information on haXe, visit ", {a, [{href, "http://www.haxe.org/intro"}], "www.haxe.org/intro"}, "."]}, {p, [], ["Implementing the server side of a haXe remoting interaction " "in Yaws is very similar to the one described in the ", {a, [{href, "json_intro.yaws"}], "Ajax/JSON RPC"}, " page. " "Most of the action takes place behind the scenes inside the " "the yaws_rpc module. The same types (array, struct, number " "and string) work for haXe remoting as for JSON RPC. " "There are just a few new things to keep in mind when using " "haXe remoting: " ]}, {ol, [], [ {li, [], {p, [], "Class objects and enums work with standard " "haXe remoting, but are not supported in Yaws. " "You should therefore rely on anonymous objects and " "signatures when designing your haXe remoting calls."}}, {li, [], {p, [], "A Yaws RPC handler can \"throw an exception\" " "by returning {exception, Obj}, where Obj is any valid " "haXe remoting value."}}, {li, [], {p, [], "haXe remoting has a few extra " "values, expressed by the atoms 'infinity', 'neg_infinity' " "and 'nan', corresponding to infinity, negative infinity " "and 'not a number.'"}} ] }, {p, [], "Following is an example demonstrating the use of haXe " "remoting in yaws. The first code segment is the haXe client " "code, which invokes the 'echo' method in haxe_sample.yaws " "and displays the result:"}, ss(A,"haxe_sample.html"), {p, [], ["On the server side, we have the file haxe_sample.yaws " "with the following code: "]}, ss(A, "haxe_sample.yaws"), {p,[], "The two important lines on the server side are:"}, {ol,[], [ {li,[], {pre,[],"yaws_rpc:handler(A1, {haxe_sample, respond})."}}, {li,[], {pre,[],"respond(State, {call, echo, Value} = _Request)"}}]}, {p,[], "The first line tells Yaws to forward all RPC calls (this " "includes both haXe remoting and JSON RPC calls -- remember that " "the yaws_rpc module handles both RPC mechanisms transparently) " "to the \"respond\" function in the \"haxe_sample\" module. "}, {p, [], "The second line tells Yaws to invoke this 'respond' function " "when the client requests the method 'echo', while passing " "the new state variable as the first argument to 'respond'. " "You should duplicate this line for every RPC method you " "wish to implement, replacing 'echo' with the method's name."}, {p, [], "yaws_rpc optionally handles sessions for both JSON RPC and " "haXe remoting. To use sessions, invoke yaws_rpc:handler_session " "as shown in the JSON RPC documentation page."}, {p, [], "If the response is in the form of {exception, Obj}, " "where Obj is any valid haXe remoting type, then the haXe client " "will invoke the 'onError' handler, with Obj passed as the " "parameter."}, {p, [], "As with JSON RPC, both request and response values can be " "composed of nested tuples of the form"}, box("{array, [Obj,...]}"), {p, [], "and/or "}, box("{struct, [{prop, Val}...]}"), {p, [], "Now go have fun! :)"} ]}}, {ssi, "END2",[],[]} ]. yaws-2.0.2/www/haxe_sample.yaws0000664000175000017500000000147012605311413013436 00000000000000 -export([respond/2]). out(A) -> A1 = A#arg{state = {new_state, "alive and kicking"}}, yaws_rpc:handler(A1, {haxe_sample, respond}). respond(State, {call, failure, Value} = _Request) -> { false, { error, { struct, [ { message, "Failure" }, { code, 500 } ] } } }; respond(State, {call, echo, Value} = _Request) -> {new_state, StateVal} = State, {array, [First, Second]} = Value, Response = {response, {struct, [ {you_sent_first, First}, {btw, "Hello haXe!"}, {also, {array, ["take", "this", 4, "array"]}}, {my_state_is, StateVal} ] }}, {true, 0, null, Response}. yaws-2.0.2/www/upload.yaws0000664000175000017500000000555512605311413012444 00000000000000

    File upload

    This page shows how to upload a file to the webserver, nothing of course actually gets written to disk, but the upload code is here in file upload.yaws

    -record(upload, { fd, filename, last}). -define(DIR, "/tmp/YawsTestUploads/"). out(A) when A#arg.state == undefined -> State = #upload{}, multipart(A, State); out(A) -> multipart(A, A#arg.state). err() -> {ehtml, {p, [], "error"}}. multipart(A, State) -> Parse = yaws_api:parse_multipart_post(A), case Parse of {cont, Cont, Res} -> case addFileChunk(A, Res, State) of {done, Result} -> Result; {cont, NewState} -> {get_more, Cont, NewState} end; {result, Res} -> case addFileChunk(A, Res, State#upload{last=true}) of {done, Result} -> Result; {cont, _} -> err() end; {error, _Reason} -> err() end. addFileChunk(A, [{part_body, Data}|Res], State) -> addFileChunk(A, [{body, Data}|Res], State); addFileChunk(_A, [], State) when State#upload.last==true, State#upload.filename /= undefined, State#upload.fd /= undefined -> file:close(State#upload.fd), %%file:delete([?DIR,State#upload.filename]), Res = {ehtml, {p,[], "File upload done"}}, {done, Res}; addFileChunk(A, [], State) when State#upload.last==true -> {done, err()}; addFileChunk(_A, [], State) -> {cont, State}; addFileChunk(A, [{head, {_Name, Opts}}|Res], State ) -> case lists:keysearch("filename", 1, Opts) of {value, {_, Fname0}} -> Fname = yaws_api:sanitize_file_name(basename(Fname0)), %% we must not put the file in the %% docroot, it may execute uploade code if the %% file is a .yaws file !!!!! file:make_dir(?DIR), case file:open([?DIR, Fname] ,[write]) of {ok, Fd} -> S2 = State#upload{filename = Fname, fd = Fd}, addFileChunk(A, Res, S2); Err -> {done, err()} end; false -> addFileChunk(A,Res,State) end; addFileChunk(A, [{body, Data}|Res], State) when State#upload.filename /= undefined -> case file:write(State#upload.fd, Data) of ok -> addFileChunk(A, Res, State); Err -> {done, err()} end. basename(FilePath) -> case string:rchr(FilePath, $\\) of 0 -> %% probably not a DOS name filename:basename(FilePath); N -> %% probably a DOS name, remove everything after last \ basename(string:substr(FilePath, N+1)) end. yaws-2.0.2/www/stats_ex.yaws0000664000175000017500000000232512605311413013002 00000000000000 out(A) -> file:read_file([A#arg.docroot, "/EXHEAD"]).

    Talking to the server

    Since we are running in the same process as the webserver itself, it is easy for us to interact with the webserver itself from a yaws script. The following is an example which produces a statistics report from the webserver. We call the server The absoluteley most simple example is a HTML file which doesn't contain any embedded erlang code at all. out(A) -> {ok, B} = file:read_file([A#arg.docroot, "/stats_ex1.yaws"]), {ok, [" \n", B, "</xmp\n>"]}. </erl> <br> Since the file has the suffix <tt>.yaws</tt>, the file will be processed by the Yaws dynamic compiler, but since no embeddded erlang code is found, the data from the file will be delivered untouched. <br> <h2> Hello world again </h2> The file <a href="simple_ex2.yaws">simple_ex2.yaws</a> contains the following HTML code. <br> <erl> out(A) -> {ok, B} = file:read_file([A#arg.docroot, "/simple_ex2.yaws"]), {ok, ["<xmp> \n", B, "</xmp\n>"]}. </erl> The file has one very simple function which just returns a tuple <tt>{ok, String} </tt> <br> The String will be substituted into the delivered HTML data instead of the Erlang code. </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/configuration.yaws�������������������������������������������������������������������0000664�0001750�0001750�00000014240�12605311413�014016� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> box(Str) -> {'div',[{class,"box"}], {pre,[], yaws_api:htmlize(Str)}}. out(A) -> [{ssi, "TAB.inc", "%%",[{"configuration", "choosen"}]}]. </erl> <div id="entry"> <h1>Build and install Yaws</h1> <p> Yaws is hosted at <a href="http://github.com/klacke/yaws">http://github.com/klacke/yaws</a>. (Prior to release 1.81 Yaws was hosted at Sourceforge.) </p> <p> Tested releases are downloadable from the Yaws download directory at <a href="http://yaws.hyber.org/download" >http://yaws.hyber.org/download </a> </p> <p> To check out the latest release and build a number of prerequisites are required. (All code example below on Ubuntu) </p> <p> <strong>NOTE: Erlang/OTP R14B02 or higher is required.</strong> </p> <ul> <li> <p> Installed erlang + development </p> <div class="box"> <pre> # sudo apt-get build-dep erlang yaws # sudo apt-get install erlang-nox erlang-src erlang-manpages erlang-mode erlang-dev libtool </pre> </div> </li> <li> <p> Installed git </p> <div class="box"> <pre> # sudo apt-get install git-core </pre> </div> </li> <li> <p> To build the docs, all kinds of verious tools are required. latex, man2pdf ... etc. </p> </li> <li> <p> To build win32 releases - the following is required. </p> <ul> <li> <p> Mingw. <div class="box"> <pre> # apt-get install mingw32 mingw32-binutils </pre> </div> </p> </li> <li> Installbuilder. To build win32 installers we're using an install builder that is free to use free of charge for opensource projects. Get the linux installer at <a href="http://www.bitrock.com/download_installbuilder_download.html"> bitrock </a> </li> <p> Further instructions are found in the win32 directory in the source tree. </p> </ul> </li> </ul> <p> To check out the sources do </p> <div class="box"> <pre> # git clone git://github.com/klacke/yaws.git </pre> </div> <p>To build and to what is knows as a <em>local</em> install, e.g. a developer install do: </p> <div class="box"> <pre> # cd yaws # autoreconf -fi # ./configure --prefix=/path/to/yaws # make install </pre> </div> <p> Alternatively, to make a <em>standard</em> install </p> <div class="box"> <pre> # cd yaws # autoreconf -fi # ./configure --help # ./configure --localstatedir=/var --sysconfdir=/etc # make # sudo make install </pre> </div> <p> The above commands will checkout the HEAD source, build it and install it at 127.0.0.1:80 with the docroot set to the local documentation. </p> <p> A <em>local</em> install does install yaws at http://127.0.0.1:8000 </p> <p> This is the typical mode of operation while either just trying out yaws, or hacking yaws. This will install a template configuration file <em>yaws.conf</em> in <em>${prefix}/etc/yaws</em> (<em>${prefix}</em> is the value of the <em>--prefix</em> option passed during the execution of the configure script). If this file exists, the old file will not be overwritten. </p> <p> To run a locally installed system, we run the installed yaws script <em>${prefix}/bin/yaws</em>. </p> <p> A <em>standard</em> install will install yaws in <em>/usr/local</em>. A configuration file <em>/etc/yaws/yaws.conf</em> will also be installed unless the file already exists. The default config file will set up the system to listen on http://127.0.0.1:80 </p> <h2>Building with Rebar</h2> <p> Yaws can alternatively be built using <a href="https://github.com/rebar/rebar">rebar</a>. Assuming you already have <code>rebar</code> installed, simply type </p> <div class="box"> <pre> $ rebar get-deps compile </pre> </div> <p> This fetches all dependencies and builds Yaws. </p> <p> The <a href="rebar_release.yaws">rebar_release page</a> explains how to use <code>rebar</code> to create an Erlang release for an application that depends on Yaws. </p> <h2>Running yaws</h2> <p> The yaws executable is a shell script which invokes the erlang system and instructs it to start yaws. The command line flags for yaws are documented in <a href="yman.yaws?page=yaws"> man page for yaws(1) </a> <p> When developing yaws code, the interactive mode is ideal. Typically, yaws is then started as: </p> <div class="box"> <pre> # yaws -i </pre> </div> <p> Run yaws as a daemon as </p> <div class="box"> <pre> # yaws --daemon </pre> </div> <p> All command line flags to yaws are described in the man page for yaws. </p> <h2>Configuring Yaws</h2> <p> Web server configuration can be supplied to yaws in either of two ways depending on whether we run yaws as a standalone daemon or if we run yaws as an embedded application inside another Erlang program. </p> <p> The yaws configuration is described in <a href="yman.yaws?page=yaws.conf"> man page for yaws.conf (5) </a> </p> <h3>Embedded mode</h3> <p> It is possible to run yaws in embedded mode where yaws is part of a larger application. When running yaws in embedded mode, it is often not possible to let yaws read its configuration data from <em>/etc/yaws/yaws.conf</em>. </p> <p> The function <tt>yaws_api:setconf(Gconf, Groups)</tt> can be used by an other erlang process to explicitly set a yaws configuration at runtime. To execute Yaws in embedded mode, it must be started with the environment <tt>{embedded, true}</tt> </p> <p> The embedded mode is fully described at <a href="embed.yaws">embed.yaws</a> </p> </p> </div> <erl> out(_) -> {ssi, "END2",[],[]}. </erl> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/server_sent_events.html��������������������������������������������������������������0000664�0001750�0001750�00000000754�12605311413�015060� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- HTML document served to start the Server Side Events demo See examples/src/server_side_events.erl for the server --> <html> <head> <script type="text/javascript"> var es = new EventSource('/sse'); es.onmessage = function(event) { var h2 = document.querySelector('#date-time'); h2.innerHTML = event.data; } </script> </head> <body> <center> <h1>Yaws Server-Sent Events Time of Day</h1> <h2 id="date-time" name="date-time"> </h2> </center> </body> </html> ��������������������yaws-2.0.2/www/api.yaws�����������������������������������������������������������������������������0000664�0001750�0001750�00000001024�12605311413�011714� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> out(A) -> yaws_api:ssi(A#arg.docroot, ["/HEAD", "/TOPTAB"]). </erl> <H1>Yaws API</H1> <p> Here we describe the API avalable to Yaws applications. First and foremost, the entire regular erlang API is available, this include mnesia and all other erlang applications that are part of the regular erlang system. <p> Here we describe the functions available in the yaws_api module <a href="yman.yaws?page=yaws_api"> man page for <tt>yaws_api (5)</tt> </a> <erl> out(A) -> yaws_api:ssi(A#arg.docroot, ["/END"]). </erl> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/process_tree.dia���������������������������������������������������������������������0000664�0001750�0001750�00000005003�12605311413�013413� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‹������í\Ýoã¸÷_Ax®¼ŒH‰”x¾ìá ´¸‡-Ú-úÈm«‘%C’ã Šöoï ©|ÙRâXb¾8ÀÆ+e<Ã!œÉŸ~þ¶ÎÈ.«´È¯ÇŒzc¢óy‘¤ùòzü¯úþ2ú)Iãáß²Œ×¾‘Wøt=^ÕõæÇ««ÝnG³û*®‹’fé–Vúê¿q–ÅW@t5þ2"ä9ƒ$®c|×¼ëºLgÛZ“<^ëëñ,žß.Ëb›'cKÕÐÍ‹¬(É]œ]?-ÌÏøªasõ‚Ï+¼7ñRÏJßv³öàG©SXot¹Ïv½)ªHêûÍIüýŒ¦¡ª€(_~ùôKðÉ6©yñÄ«­¡Bêu\.ÓüPôMf;‚ÓˆsþÐï1s/"s/¢t/"­n6EY—qZŠ™E¦ãÜJªË­>]N53€Ìkª°Ó¹/Òº.Þhÿ"Ϊc°¯gÏ{gâ²L“×'â Š.»4©W7ßu—å~ïˆû]Z¥³L·µ>ÍëÁØßÃ~tŒ5~úzO4Xnæ>‰´Ðâýæ~¹M]½³—4œV ÙÕ[½¾OwlÇØW{Î׈Èâ{]6ìÿðävI3ÀÅyÖ Åì_z^7êý½Žó$.ò™ü1ËÒ Ìí§Hâˆ4¹ÿÅ{ÙEûJC°~}´)ž€ROL£þ¾æ‡v£KÂl¶/ 5â|™é!(‹)÷)›0Ÿâ4i:Óë›yQ懎~@ŒcBõz0²ë•N—«º›7§ì îö¥…Ëøùª¿Õ-àa}ÁãTŠI�½í<V`&�’rЉ¤Qt¢Ð;ã ¹GÓåòMø‚n/žüºŽÅ&Ów:#›²˜ëªšÞ.u~SéÆd”èEšë„¤9¹w¼†·T—%ÓË´ªu©“Q\‘š?ã·~ 0º¤ªã²†¯Îî‘éW[ˆ‚Á€ ~d¸Ý »ŽÐöÿÑŒyݦ5¾'‹xf÷Ð9q^¡÷hè�qö«¿êìN×é<~nßß‚ƒÔ2‹<õòûÇâÿI/è+™“çõ!ê2_ëöáÓùvÝtÝ‘RZ]ä0&«Ûåñ¾V‹GT1_1—† åxFN(ű‚O‚*éÔû  ÞoÎv£Éï&†£ìMØ+‡A %i(,š˜[4õWï¡)èŽsê{£ì2"çŽ9l‹¨oѹµM¨÷Ð$zÇçeÂdBSÛ„rlÆ€mò!FÇ'À–[Û4€zM²/šBã 0­v ¦Ðø9X¡ŸƒáKý•û@P {»9…+4Z8õq %LÁ«± §Ê©_ë©Ïo;Nó6àD½=ZHý‰¤Ž×›X¤H |øÏEʈ7)všäy‘ç7:OŒ*ïS°kÙWTOk äùóÍ~ÚJ ïÂYžÜÄeYìö?-+pÞ“õM¦óåksÄ;O"Þ˜…oKfmVõž)œbHïr¢ 0+|A_ báñ f!yQ®aPŸ–K/Ë£ƒ/îCð²6êÒ¹²ÞÅ@ŸQ…3Z¹\ÇÊG!KJ…Q §€Ïó'ø›Ÿãï^5lYóT¸x׳÷®]S¥éþˆ.g Ì¥âð9 åžÇ&XVð<éz¦(xH-b†è»L• Ð»žäû”C'H—¡Œ¤$0òò ؉‚Ù=Î’íZiØ÷KHÚ Ñ»äׂ1C$X!àÀp7DHŒ¹Y@Å9ì†0›²b9!e³¯!5›"Èn•ÎWdW‚Ôj„[ve¼©PW—À|èÀ¼ ©—ØÜ©—é]äœú¸ йŒ88åB)|ð)<ž |á‘cOÓ¢a;¶çŒŽÞe=† ͲÊé :î90â”Lx| Ï‘'USèSŽñÐ¥f;eÏêÍ Yª=Ã]¸Ô‡¿�} “º0u9òô×QL‚¡`ç‹gÆG0Ç0Tà¯Lž!Å”c­ÙbIéƒ]:¶SzÒ4‹É3ƒÃ`¡&Š:Þ …É2 Ï`“Xh&¿ðÏdKp/ôz³•wB¶•NÀŒâ4!¿~ýúWÜ×[ëÏ‹m¦¡¸M5™ÅîÞl2ˆA-¸DÅCGŇÀ½ÄÄN¡h€•Öìq»¿ÉÄ݆fýÝ‹(îWâÚµl'4m:—ÈkB ñ2’ÿ¯¨‘UA6ÂÜ.+Ê1œES” Á¸ Ÿ®Áw¨á!‘¢¦9gœ”ñþé L'8„Ö„Á‚Rb ϳj¥ç¹.žµ©ØNeZ$θ*ÀÙ�µÔÀf¨Àl;õNÌìÞf&I™Â¸${üCº¯¦¶ëØNÚK åY#£ÿù#W+L¯ùn‘f¡ž¾ û :>sîÒ²‹´×“ï·|ã;^¾éÈÓyÿƒKXà§ŸÅ>¶† B8°\ÅšT‡Ô;‡zÕóóßýþáà®®&¤ÈõhiœŽç+’a +‚ª˜ßꚎ ·¯4‰KmŽø>~mT¯âšÄó¹ÞÔ@=ÏRÈÚÈè2.ÉüàÉ| º/é¼SÇ p\‰›ChŽ]b¨ÌY·+³|ÈÑù`J: [4lw‡¶Ag%‰âgÆ›#®¾Û()¤* ”—Ð 0‚fÊ q ªeîcèv=[Ov[¤žsø,�FdzËmJ’HÀ'îQ „¯°ï}ÏWî!±¯aëæêÀ‰sC8À)‡Ð\nO:ÈȌӀOs•I‰ÝÏàÓ5Útl!“¸ —ªÏýkf˜„ãr€âÊÈ Bܘ˨äÀSÎÝ—lÙ˜Ëðä´‡^¹ë¥÷ =‡±i¢)î4ˆ@ 9áNy`¥ŠÓ¥y=GõŽ9{ŠÙ”Ãã§ìmöÃ]øâ Pô‘vvq§wt ÏÎb)¦·RƒÓ¥y«Bõ>¤†¸HfÑzHÇg›…M!– B+Uœ.õHHõWï£Aа˜¢lŸÌñÝ/ÊBÊ—ædв œßýÒW½©þi=ƒïø”Ó@ ¯:kü‘èy5ËÛ±Tõ~“ê¨@ù½×{!‹¶ËY.Ád…p{` Ãe¬@ù¸äw¨å­.Ÿ*I”ØÓã ²Ôõ¨ÚÄ»üñXbÊV†’,Ò²‚]3S² $yÁ!)HZ‘º €¡Ä0À-¨£<Á“EY¬ÍÛ¦l…g³êò¿°H—ÛR“b[ìñ­»´¬·x©‚Ù×Jvšì⼞”jJ6éü–ÄäS™îâßÿÁ8eBɳKm§qV›+ÿRºÖ6Õ.å°ãÌ£}6—¹½¸íýËèp{a‡áe�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/index.yaws���������������������������������������������������������������������������0000664�0001750�0001750�00000012550�12605311514�012262� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> [{ssi, "TAB.inc","%%",[{"index", "choosen"}]}, {ehtml, [{'div', [{id, "entry"}], [{h1,[],"Yaws"}, {p,[],"Yaws is a HTTP high perfomance 1.1 webserver particularly" " well suited for dynamic-content web applications. Two separate modes of operations are supported:"}, {ul,[], [{li,[], {p,[],"Standalone mode where Yaws runs as a regular webserver " "daemon. This is the default mode."}}, {li,[], {p,[], "Embedded mode where Yaws runs as an embedded webserver in " "another Erlang application."}} ]}, {p,[], ["Yaws is entirely written in ", {a, [{href, "http://www.erlang.org"}], "Erlang"}, ", and furthermore it is a multithreaded webserver where one " "Erlang lightweight process is used to handle each client."]}, {p,[], "The main advantages of Yaws compared to other Web technologies" " are performance and elegance. The performance comes from the " " underlying Erlang system and its ability to handle concurrent " " processes in an efficent way. Its elegance comes from Erlang as " "well. Web applications don't have to be written in ugly ad hoc " "languages."}, {h2,[], "yaws.hyber.org"}, {p,[], ["The www page for Yaws is ", {a ,[{href,"http://yaws.hyber.org"}], "yaws.hyber.org"}, ". The documentation, examples as well as releases can be " "found there, and of course, ", {a ,[{href,"http://yaws.hyber.org"}],"yaws.hyber.org"}, " is itself powered by Yaws."]}, {p,[], ["Code is on : ", {a,[{href,"http://github.com/klacke/yaws"}], "http://github.com/klacke/yaws"}]}, {p, [], ["Travis test results at :", {a, [{href, "https://travis-ci.org/klacke/yaws"}], "https://travis-ci.org/klacke/yaws"}]}, {p,[], ["A mailing list exists at: ", {a,[{href,"https://lists.sourceforge.net/lists/listinfo/""erlyaws-list"}], "https://lists.sourceforge.net/lists/listinfo/erlyaws-list"}]}, {p, [], ["A lot of excellent" " engineers have contributed to Yaws over the years, " "we keep a list of all " ,{a ,[{href,"contributors.txt"}], "contributors"} ]}, {p, [], ["A high resolution logo created by Tomas Selander exists at ", {a, [{href, "yaws.eps"}], "yaws.eps"}]}, {h2, [], "News"}, {p, [], ["To see all the most recent changes and activity in Yaws " "development, please visit the ", {a, [{href, "https://github.com/klacke/yaws"}], "Yaws github repository"}, "."]}, gen_log(A)]}]}, {ssi, "END2",[],[]}]. is_proper(10) -> false; is_proper(Tag) -> case string:tokens(Tag, "-") of ["yaws", Rel] -> IntList = string:tokens(Rel, "."), case lists:filter( fun(IntStr) -> case catch list_to_integer(IntStr) of {'EXIT', _} -> true; _ -> false end end, IntList) of [] -> true; _ -> false end; _ -> false end. cd(Git) -> ["cd ", Git, "; "]. git(Cd, Cmd) -> os:cmd([cd(Cd), Cmd]). head(Tag, Dir) -> Date = git(Dir, ["git --no-pager show ", Tag, " | grep Date | head -1"]), Ret = ["Version " , Tag, " " , Date], Ret. gen_log(A) -> case os:getenv("YAWS_GIT") of false -> []; Dir -> Tags = lists:filter( fun(Tag) -> is_proper(Tag) end, lists:reverse( string:tokens( git(Dir, "git tag -l"), [10]))), gen_log(A, Tags, Dir) end. dlog(Last, Prev, Dir) -> Str = git(Dir, ["git --no-pager log --abbrev-commit --no-merges --pretty=medium ", Prev, "..", Last, " | cat"]), Str2 = lists:zf(fun(I) -> if I == $< -> %% XSS false; 0<I, I<255 -> {true, I}; true -> false end end, Str), Lines = string:tokens(Str2, "\n"), lists:map( fun(Line) -> case Line of "commit " ++ _ -> ["<br/><h3>", Line, "</h3> <br/>"]; _ -> [Line, "<br/>"] end end,Lines). gen_log(_, [], _) -> []; gen_log(A, [Last, Prev | Tail], Dir) -> Head = head(Last, Dir), Data = dlog(Last, Prev, Dir), X = [{'div', [{class, "news"}], [{h3, [], Head}, {p, [], ["<pre>", Data, "</pre>"]}]} ], [ X | gen_log(A, [Prev | Tail], Dir)]; gen_log(A, [Last],_) -> []. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/arg2.yaws����������������������������������������������������������������������������0000664�0001750�0001750�00000001643�12605311413�012005� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> out(A) -> Peer = A#arg.client_ip_port, Req = A#arg.req, H = yaws_api:reformat_header(A#arg.headers), {ehtml, [{h5,[], "The headers passed to us were:"}, {hr,[],[]}, {ol, [],lists:map(fun(S) -> {li,[], {p,[],S}} end,H)}, {h5, [], "The request"}, {ul,[], [{li,[], f("method: ~s", [Req#http_request.method])}, {li,[], f("path: ~p", [Req#http_request.path])}, {li,[], f("version: ~p", [Req#http_request.version])}]}, {hr,[],[]}, {h5, [], "Other items"}, {ul,[], [{li, [], f("Peer: ~p", [Peer])}, {li,[], f("docroot: ~s", [A#arg.docroot])}, {li,[], f("fullpath: ~s", [A#arg.fullpath])}]}, {hr,[],[]}, {h5, [], "Parsed query data"}, {pre,[], f("~p", [yaws_api:parse_query(A)])}, {hr,[],[]}, {h5,[], "Parsed POST data "}, {pre,[], f("~p", [yaws_api:parse_post(A)])}]}. </erl> ���������������������������������������������������������������������������������������������yaws-2.0.2/www/websockets_example_endpoint.yaws�����������������������������������������������������0000664�0001750�0001750�00000003526�12605311413�016740� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> %% To use the extended version of the basic echo callback, add %% 'extversion=true' in the query string. CallbackMod = case queryvar(A, "extversion") of {ok, "true"} -> basic_echo_callback_extended; _ -> basic_echo_callback end, %% To enable keepalive timer add 'keepalive=true' in the query string. KeepAlive = case queryvar(A, "keepalive") of {ok, "true"} -> true; _ -> false end, %% To define a keepalive timeout value, add 'timeout=Int' in the query %% string. Tout = case queryvar(A, "timeout") of {ok, Val} -> try list_to_integer(Val) catch _:_ -> infinity end; _ -> infinity end, %% To drop connection when a timeout occured, add 'drop=true' in the query %% string. Drop = case queryvar(A, "drop") of {ok, "true"} -> true; _ -> false end, %% To reject unmasked frames , add 'close_unmasked=true' in the query %% string. CloseUnmasked = case queryvar(A, "close_unmasked") of {ok, "true"} -> true; _ -> false end, %% NOTE: change the line below to %% Opts = [{origin, any}], %% if you want to accept calls from any origin. Opts = [ {origin, "http://" ++ (A#arg.headers)#headers.host}, {keepalive, KeepAlive}, {keepalive_timeout, Tout}, {drop_on_timeout, Drop}, {close_if_unmasked, CloseUnmasked} ], {websocket, CallbackMod, Opts}. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/appmods.yaws�������������������������������������������������������������������������0000664�0001750�0001750�00000007123�12605311413�012614� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> box(Str) -> {'div',[{class,"box"}], {pre,[], yaws_api:htmlize(Str)}}. tbox(T) -> box(lists:flatten(io_lib:format("~p",[T]))). ssi(File) -> {'div',[{class,"box"}], {pre,[], {ssi, File,[],[]}}}. out(A) -> [{ssi, "TAB.inc", "%%",[{"appmods", "choosen"}]}, {ehtml, {'div', [{id, "entry"}], [{h1, [], "Appmods (Application modules)"}, {p, [], ["Appmods are a way to let the application programmer take control over the URL path. Or put in another way, to let the application programmer fake real paths in URLs where in reality an Erlang module is executing. Possibly an example will make this easy to understand. Say we have the following URL"]}, box("http://yaws.hyber.org/pathelem/foo/bar/x.pdf"), {p,[],["With the above URL, the webserver would try to deliver the file \"/pathelem/foo/bar/x.pdf\" relative to the docroot. However if we had specified \"pathelem\" as an appmod, the server would stop processing the URL after seeing the \"pathelem\" part of the URL. Say we had the following in our yaws.conf configuration file"]}, box(" <server tita> port = 8001 listen = 0.0.0.0 docroot = /home/klacke/yaws/yaws/scripts/../www appmods = <pathelem, myappmod> </server>"), {p,[], ["Then the webserver would invoke ", {tt,[], "myappmod:out(A)"}, " instead of trying to deliver the actual file. When shipping such an ", {a, [{href, "/pathelem/foo/bar/x.pdf"}], "Url"}, " there are 2 fields in the #arg record which are especially interesting. If we have the following code in \"myappmod.erl\":"]}, ssi("code/myappmod.erl"), {p,[],"The #arg field called \"appmoddata\" contains the remainder of the path following the encountered appmod and the field \"appmod_prepath\" contains the part of the URL path leading up to the appmod."}, {p,[], "Thus the following URL"}, box("http://yaws.hyber.org/zap/pathelem/foo/bar/x.pdf?a=b"), {p,[], "Produces the following output:"}, box(" A#arg.appmoddata = \"/foo/bar/x.pdf\" A#arg.appmod_prepath = \"/zap/\" A#arg.querydata = \"a=b\""), {br,[],[]}, {p, [], "Appmods would typically be used by web applications that want to provide the illusion of proper paths to the browser. "}, {p, [], "A special case of an appmod that is particularly interesting is the '/' appmod. This is used when we want the application code to handle all requests. This is common with web frameworks such as Nitrogen."}, box(" <server tita> port = 8001 listen = 0.0.0.0 docroot = /home/klacke/yaws/yaws/scripts/../www appmods = </, myappmod> </server>"), {p, [], "The above configuration snippet is an example of a slash appmod. One complication with the slash appmod is that usually we have a set of folders containing static data, images and java script, and we want yaws to just deliver those files without intervention from the slash appmod. This can be achieved by excluding a set of directories."}, box(" <server tita> port = 8001 listen = 0.0.0.0 docroot = /home/klacke/yaws/yaws/scripts/../www appmods = </, myappmod exclude_paths icons js top/static> </server>"), {p, [], "The above configuration will invoke the 'myappmod' erlang module on everything except any file found in directories 'icons', 'js' and 'top/static' relative to the docroot"} ] }}, {ssi, "END2",[],[]} ]. </erl> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/websockets_autobahn_endpoint.yaws����������������������������������������������������0000664�0001750�0001750�00000000300�12605311413�017071� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> CallbackMod = advanced_echo_callback, InitialState = {state, none, <<>>}, Opts = [{callback, {advanced, InitialState}}], {websocket, CallbackMod, Opts}. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/session.yaws�������������������������������������������������������������������������0000664�0001750�0001750�00000001053�12605311413�012630� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> {ssi, "TAB.inc", "%%",[{"session", "choosen"}]}. </erl> <div id="entry"> <h1>The session server</h1> <p> The Yaws session server is ideal (and recommended) for maintaining cookie state in a server side application. </p> <p>The code in <a href="code.yaws?file=/session1.yaws">session1.yaws</a> shows a minimalistic way to handle sessions. To run it click <a href="session1.yaws">here</a> </p> <p> The actual session API is documented in the man page for yaws_api. </p> </div> <erl> out(A) -> {ssi, "END2",[],[]}. </erl> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/redirect.yaws������������������������������������������������������������������������0000664�0001750�0001750�00000006213�12605311413�012751� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> out(A) -> {ssi, "TAB.inc","%%",[{"redirect", "choosen"}]}. </erl> <div id="entry"> <h2>Redirects</h2> <p> Redirs are a powerful tool in the webapp programmer toolbox. The Webserver returns a specific status code (302) and adds a "Location:" header to the responce headers to the Browser. The Browser then displays the new page as indicated in the "Location" header.</p> <p> Yaws supports a number of different forms of redirect return values from the out/1 function.</p> <p> The code:</p> <erl> out(_A) -> {ehtml, {'div', [{class,"box"}], {pre,[], {ssi, "redirect2.yaws",[],[]}}}}. </erl> <p> Clickable <a href="redirect2.yaws"> On this link </a> executes the above redirect code. </p> <p> The code above redirects to an external URL. The HTTP RFC mandates that the Loction header must contain complete URLs, including the the method, http, https etc. A very common case of redirection, is a to redirect to another file on the same server. The code in <a href="redirect3.yaws"> redirect3.yaws </a> shows an example of a yaws redirect relative to the "current" server. </p> <erl> out(_A) -> {ehtml, {'div', [{class,"box"}], {pre,[], {ssi, "redirect3.yaws",[],[]}}}}. </erl> <p> The code in <a href="redirect3.yaws"> redirect3.yaws </a> will do a relative redirect to the code in <a href="redirect2.yaws"> redirect2.yaws </a> which in its turn redirects, once again, to google. Double redirects. </p> <p>While working with redirects, the tool <a href="http://curl.haxx.se/"> curl </a> is an excellent way to troubleshoot the behaviour of your redirects. For example:</p> <div class="box"> <verbatim> # curl -I http://rubin.hyber.org:8000/redirect3.yaws HTTP/1.1 302 Found Server: Yaws/1.49 Yet Another Web Server Location: http://rubin.hyber.org:8000/redirect2.yaws Date: Tue, 16 Nov 2004 20:16:01 GMT Content-Type: text/html </verbatim> </div> <p>Where <tt> http://rubin.hyber.org:8000</tt> is where I am currently testing the <a href="redirect3.yaws"> redirect3.yaws </a> code. Learn and use the <a href="http://curl.haxx.se/"> curl </a> web client, it may not render pictures pretty, but it sure displays headers. </p> <br /> <p> We show one additional version of redirect code. The code in <a href="redirect3.yaws"> redirect3.yaws </a> requires an absolute path. If we want to supply a path relative to the current url, we can use either the Redirect modifier <tt>rel_path</tt> or <tt>any_path</tt> as in : </p> <erl> out(_A) -> {ehtml, {'div', [{class,"box"}], {pre,[], {ssi, "redirect4.yaws",[],[]}}}}. </erl> <p> <a href = "redirect4.yaws"> Clickable here </a> </p> <p>You can also redirect a whole site via virtual server configuration. For example, you can redirect all port 80 requests to port 443 like this:</p> <div class="box"> <verbatim> <server vhost1.tld> port = 80 listen = 0.0.0.0 <redirect> / = https://vhost2.tld:443 </redirect> </server> </verbatim> </div> </div> <erl> out(A) -> {ssi, "END2",[],[]}. </erl> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/simple_ex4.yaws����������������������������������������������������������������������0000664�0001750�0001750�00000000240�12605311413�013213� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <h1> simple ex 3</h1> <erl> out(Arg) -> {html, f("Printing the arg structure :" "~n<pre>~p~n</pre>~n", [Arg])}. </erl> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/HEAD���������������������������������������������������������������������������������0000664�0001750�0001750�00000000537�12605311413�010672� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta name="keywords" content="Yaws"> <title>Yaws</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <link rel="stylesheet" type="text/css" href="stil.css"> <link REL="shortcut icon" HREF="/icons/yaws_y.gif" TYPE="image/x-icon"> </head> �����������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/ssi/���������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311413�011117� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/ssi/dynamic.3������������������������������������������������������������������������0000664�0001750�0001750�00000000501�12605311413�012543� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ -record(http_request, {method, path, version}). -record(headers, { connection, accept, host, if_modified_since, if_match, if_none_match, if_range, if_unmodified_since, range, referer, user_agent, accept_ranges, cookie = [], keep_alive, content_length}). �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/ssi/dynamic.2������������������������������������������������������������������������0000664�0001750�0001750�00000001066�12605311413�012551� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-record(arg, { clisock, %% the socket leading to the peer client headers, %% #headers{} record req, %% #http_request{} record clidata, %% The client data (as a binary in POST requests) querydata, %% Was the URL on the form of ....?query (GET reqs) docroot, %% where is the data fullpath, %% absolute path to requested yaws file server_path, %% The normalized server path pid, %% pid of the yaws worker process opaque %% useful to pass static data }). ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/ssi/dynamic.1������������������������������������������������������������������������0000664�0001750�0001750�00000000153�12605311413�012544� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <h1>Foobar</h1> <erl> out(Arg) -> {html, "Funky Stuff"}. </erl> <h1>Baz</h1> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312016�013022� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/Makefile.in�������������������������������������������������������������0000664�0001750�0001750�00000035646�12605311446�015033� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = www/shoppingcart DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = shopcart.erl EXTRA_DIST = $(MODULES) EBIN_DIR = @top_builddir@/examples/ebin EBIN_FILES = $(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign www/shoppingcart/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign www/shoppingcart/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: ������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/loginpost.yaws����������������������������������������������������������0000664�0001750�0001750�00000000065�12605311413�015666� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> out(A) -> shopcart:loginpost(A). </erl> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/logout.yaws�������������������������������������������������������������0000664�0001750�0001750�00000000210�12605311413�015151� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case shopcart:top(A) of ok -> shopcart:logout(A); X -> X end. </erl> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/junk.png����������������������������������������������������������������0000664�0001750�0001750�00000107322�12605311413�014424� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��¿���S���â ?���gAMA��± üa���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEß Š5$�� �IDATxÚì½{°å×UßùY{ÿ~çqç>ú¡nuëmY¶dƒ± FØø‰0X2Ä ’xRq2@ª23Ÿf \˜I%™d† •LÁ$HH !1[±±eK²,Éz¶úý¼}_çõ{ìµæ½çœÛjɘQÛÜ]ut»ÕçžÇï·×^k}×w}—ð"VXy§�N0L ¨zSq&hü-[ýnÁ 3š·‘æ_qðöÞ»kw}=-]y‡€E“ @Àh"‚¬x×–v××ý’ò¤áê;¥€<·Ô6»J5ì´kBaå:ØÙ n«2W›8 œCÁ°M«BŸ:°¡}Y6o]¼u%CA¤ƒ˜š©Ž1«ÄáŹ6Þg’å˜å2³›‚UˆÔ ø¾ÕœÓQ½‚+–$«„ £³ù±]#Þ]_»Njõâ0u`ˆ!"˜35³L\@$`š\‚™Õ(1ç2ÀK´5ÉÀÚ`mÌÚ 35ê+±ª0­ Pu[ŸØµ¡Ýõ—ÏùU«÷H!’f«Àkzâ,ƒ»±ÓššŠ‘U´Mh»ìw ÿ\-./ ûjÓV_«ã::£pv´.dâú|Ø/­B\H[°FfÔçŒp6˜ Eܦ…}¹¸›ö¿²¯¬ /³}+ÀN ²®£«O…mÎèèéW¹ùOïu­‡ ôè�Ý<gÕè¬õ'ë ýéâÈ¥F¼kÔ»ëŠ]aÏ÷e Ëbz]­åÁæy`Y°‹¨Ëv'9®°‰8Àf°‘ˆ&™:q]19à‘Ûð:Óp— 7‘P”d["¶eZѬþغU÷]´ú©O†­þûÆOê ”Ù½[_»k{å;Å#df"qóàg¼µå·Êª›Ó*Ýn! P¶ ÒFd'™©eb*ô5±'äòç»ÜXh,ì pG ÷c=Éî—)h‰ZEe5f q(ˆàIe¤Êœxæ},°iKÒñ p10e¬%q|Q‡ Ìxm¶LÏuÓsJLCÌMÓGjŒó6fXrÝhaD@~×ÃGDüG­8{:Œ¶ ýÁ/W§ëO†-½Ähw xw]1k¼z¯oI~‘ÆôýXf¶i‚ÿMqbéÿ8À5ŒaR ¾�ߋޱùõh›Ø¥f  5[VpLǬYýw<ò;{%»ø ƒ5ù̇¸üÏÝuÅ# ÷:‘<{¶Þê^°ñÜU’w÷ŠwbZ×è0 Õ“: ë¦òmùþÜ»VÛé¨mV«™©Ç˜mXhå⯖Ί@Ku¼QZyâ³õúÆ¿©Î×ÿ²:cWr°”=/ÛÛó½Y?°®ã»+Âö»öá®´˜O2M¦–‘EG$C�G Èq,x¢£“¨i™¦¿ k¡BR­a‹š�Ô*œÑ’ëü<½l $ƒe)°mÀèü<°‡m\zn…ˆ#Ãî»×IÆÕ~î—FVýÞüÒŸnZ½öˆËt#vàV[|‘7ï·f_#ÉaE'%s63Kö'é9ñï¶ö4ÎMÿ.®yÚtËÛôÏ[8¢Gtô‹Î]çÚF@'=I/ó]û¹ò—íýAï¬búM×[¸·k¼ó ´ƒ€•`ò¸Â£{¥µ1'š/úÎ5 ßlX/î3ÈÖY-¹@Ù»YÉ]–‚³šÇBÿ?<¥ãò¶lù‘‡Âvýyè—9[_ò½²ÃùöÜë ¨ý‡öž=®M×uâ¾Ö¬À€J .XbÌ;Ï Y´1‰aM m’ŒKâ…±�@G|r~®1tÚ&”ÄkÔó-æ]›ýÙ"¸„èÓ0ã«b‚Nr·ñ=k2 ¨ÀEã7£$PØ´ê}]qï{}¶ôÏòKóaýÙÏ„íqJ?w xw]‡ÓžïL3´¸Ñ,$§ægœÍÀ6’ì(Ø8ÄÿŸ Êá’¬Ï&ÿVXÅñPØæQ È[¶mî»}ü–á#ËÉNPez¤´qw]Ù{ë^íaåaö³Î9Ú\JBs+o+ÐÛÆÔœÐ‚ÛuÒÆJŒåé0ì=®C®q]ö¸„âiÁ-x\‡ï^³ê]qon‹;‘öÉ,e;ŒN²¿é‘÷àÛ,ÐŽŸ¯Þb³^ç“õ&_Чµdh/BÏ5®Ãí~ž[Ý"ޱÀªäôÒËׯ$Kq1“zyrf«’`ñì—¯ÖÛ ÛŒë!kVQb´öJN.A†¡(†à‘óF£¯E©p¨Ž.Ž9ܼ-_>T¢ÿ¸oá™/êp˜nP=cÀ»pw½$KÖ~ÛlùmŦ?s<Œ¹hÂ×âz×A¤Å,Ëy’Õ‰&NÌ¥'žÍ8:›Bžhr’Ñ‚6¬æ¬–<®C>Uoñé°Å1Ó“Œ%Él+¯“ã+€!ÐOïRìŸ_ÎOÕ‰+¯×Pþ¬à°”$ˆÕ@ÀL8ÎhÉ}õ:‡‹Ò敾ÇPP“!<6Ù°šïÊ€_�‹GçÀ”‹Vs^Ë} ïZø­´G®È`išù‰ójv›>èp,àÀÆ„ò¿\å¿V|I‡œ×’"¹—6Ž%É8äZ³‚GdÀ~—ó~žÏS$Yc@ ‡HbXk´?_Ö¦dyšMP Vó¸ùbèó¤Ž(M¹JÚÜì»v-–ÉXv9­ÆñE\4µC$¾GG2–‚Xº9Õ=ßšõZ§­üÙ¡é“ç¬ÚîFé…]#Þ]/¥ÿë‡ayLG÷IGï9®Å¯—(Ëšq½tx™ïrXÚ´gkxÈå²³ªo6q‚†Q›±Mà´–<¦>|>ôùbp¼9£ŒþJuö»©:S¤«ÀFz±ú»Ù]WèúB½îo÷‹‹ D|Ì&йJÊÏXÉŸ†-ž®s]îÊWÀu¸ªS,HÆE×åk³œ­DDOX(ØJÔS6"(ïX³úŒ¯Ä`)(Wï‘…¥ ùag‚Çpêêÿgy‚ÿT®ñí³bÉieÈ GŠé|_C{Ÿk0gUr —LMÄ’C³‰=*D3kÊc¨1íþlØæ£õ:é‡p£ëržŠWØßè¸ !“æ6êÄæ±gBpÉÁ΋gQ2¶-P™Þýײ}‚Ùÿñé°õš­Ñaº1»pw½$ŽÅíOùÃÒªHë¡UɾI²÷vpïèdŽyõÌ;ÏU’'”#Ú•Ì H³›Vlö¥m²±+3úŽé˜Ï†m>Voð@Øæ„ÔÓ_ÿ£óÔ·×Ø6M;`<ÈòäôFÉ:vKWü:¥}}™È…‹Zn°¢wFKƦtÄs•ËY&ã9óPØfx~¼u|0®v<IÆë¬fɵãÐBŸ¾•\°Š³Vr"”±;†®7è&Ç·19ÞãÞyɃ¥ ÀK–ep‡‡÷fMD >[oñh=äY€9©pp>@ɯµ«ÍÛ·þhëê·Üææh!±×ˆ£0M°äL (B&Éù%2Ki¡)'­äó¡Ïýa›glLÇ&5ç¬ä[óÌãÈÄÇkJeJ†àœ›Ä·’¬ÄÏÏ~É—2@«^ýZßû'­üñ>;De&2Ùu€»ë%s‚'¬”sVUr|äÿîå®{þOÂÖ{¿ÁÏ‘‹LÂE™äq6Åì“IŠæ›m,€Z|^²¦†©ÖùxØàâô<Úrða#5æ-¶X4E¡†õévoÓ×ÖúL½®¦Õ©- ÷,Õ¿;¢c¶µ&ÇɸÁw0ƒ%÷d«tüh‰0šƒÚª¸t�Z,P`ŒM)ͨ^…°¸E·ÒG%GxEKÙ³Ëo• «–V]÷G§d’�V²Nà¨i‹£‡gËÂ' ô˜ÂÈ¢! ÔÔ`œüOÕÚÖ»ò=ß_&òAç"|.2[¯"Li,e2Üc@àŒ–Ñ1ÏÙ¸¹JUfçÅÝõÛÕîô‹Ôð ·M'×x.‹qñ€èÛâX%#�Ïê˜Ö<¶{C ÿc.ò“¹ÉSÕô~ì:ÀÝõR.+1+±zlÅÅZíÓ‡\kù°tî]•,±«¡o tÄÑ57ñHrI:Ù8EMÈÊØ”sVòHðyíÏ:¾xxÒ`K¡´èìx³LØ(e€Í »6rå¯Gí¯çûË’Ý·nÕ›Îkõ–é{+ìšÃ®Í +qÀM®Ë-~¤o{èóœˆý}™õf hE…Q™ˆgweF)F€¥ˆs@d 7Ôey©¯Göhè»[Åߨ3ÿîVs. Ù°šWûyJŽ‹øßúÕúÜ­`}‹| TtÓjNX¹õ[Õ…7þíÖÁÕ® &I™H$¡È ËlâøÌ˜r9£M9ŸÒèŸ;Tì3¬Ú<bų׹Îßì[ k5-É‚‘YÒÀHŽo‹ÀšU쓜"ËtGaÊq£€GîXÁ¿ºOب°zâÙ5êÝõ’8>¦Ä’Âú†Õ¶fá÷¸ö½çPúVQY`dñlÙKNgBøš:»ÙÍñ&K/íë9sΪæ)è౪"=Êô³©Ûl%k3ý½Éw××Àúµêœî—¼oð¤[-‘/Îáî„ðNnÿVߣ+\V8£1ùXÅÓÅÑjȉP”_Qa”(u<Ë[ÄV›6*÷3YßK¾²We«­kòÕ;1Ň›ZPëˆ5W»·Úm›h!oo!GF±°A,`ŽZ£¼àqêâÞ‡8ëð¦ÔXŒl§/¹ô*4§@é[`lJ${Ëj¸X¢[§µ<?òú»=Éî„ Èñ´P¼LƒŠ€qÁ*J3æ%^÷E¦j& ®CÛ„ÀÀ#3ÝñwYl»ëÿO§G2¦¦æš?·Äç•8NkÁÃc´HÎÕÒJgK´wÉ‹ Pa(‚P`l[ o:i3Ê#56H60˜yŒgþ_æÑ0¥g褻ëJßcç¬ÒtO7½qÜ#Eîé|Ï;×½õ_l ´b¤ âR9Û¹«L ØŽÀª2ÅbKÎù5ɳé¶0¾3Äy–Ô¨€ž´Xrž9<‹äYÂûr䧆SæÎÆŒq„�YK²?Aüû@($Üs"‰æÏ +Œ>uJ¯ãÅl‰£e‚ k%:2è›ç­úÄ‚ó÷ž–ääâR/aT®8e%'´`„ò2×¥ír°ÀQSJLÝ á˜Ž9c%mœÔØRŠh£/Ø-äï®—Æ ÖÉ®4íÃþunÎ/H¶uƒtz]—G”FÃN ³I"6LJ/ œÑ’5«Y•œ=.›ØbŽãȰ5Œ ƒm`=Ù÷vrr ÔÙü,x~‹ÐîúÚXMývàbÀÂ&a€?Öò­?ÐîM¸ºÒžÅÍgöWÌöÂ]ˆdF“¨/´mÁÙ~nf¢}Á†ó“¾CK½w’3Œœ³Šgm̦UXÄmeæ"ŽG±(™\åÚÏF®h,±g8œÄ><̾¬¥(Ÿ[|´^ç&×eŸDã^–Œ..q¬¥lPc7M/|<ô¯ô‹ó]1Åi Ô¬YÅ'êMþc½ÆŠd¼-[ḩªa\#6¥¦OÍi‹­ ý€u€¹™4}·¨¿»^Êì¯AÊždþe®››ÙKâß,åq E²Æ)ð"lkˆÈÊ£aH‰ñ¿@mžÈhçȃ$\F›šÞpXKÁàˆiVãðjv–vį½½5lŽ_Å=—ÛU¾·±LÝO·Ø.éÎMaÂÝhA2´@m†aãKùye8¿JÇÁpWV1D©BŠÀºÕ<­c¾¤CžÒ¥e2»éÑN"�åœx]üì¶(#3æpt$ ÒMÓ·6r„FR7� <ªC~«ºÀY+ùßãf×eD`¯ËȂÄeoª cm±Ã?æÅ¿vÛ”M+©¬äjÉXŒ×f=*ŒWºynós|ªÞbE2îð Ì‹çq°fý«&OÓ£‘ͤê²k3»ë%:¤&ÇY+«Wø…­RøSoòfgŠ›mZ·š:• Æ(C œ²’¡)û$ç•~žë\‡«|,p\·éˆCm‹æíx¶®w1ý¹˜7g¥–vß×æÒ©g‹~«…^ï—e6©—Ñ ³T¹³š:1æ>ÅÎÍjØJ1ŠB?ñŽg[êKáKëüΆa‘»ü¾£:þÉ3V2²¨—RcœÓŠCŸ/Ô}ÎQ‘Á'%v-¦(°1ØÀB½*­q‹Œ¶@Ç¥FwAEl¬lœ_ÀPƒ5«xC¶Ä›ý2×¶€ Ѝ1Y‘…B„ÑM~~í°›Kº¡Qp» ,®¶Š<×úyð=îõK1Rè×› gBÉ8ö">a¤wcÔ»ë/¥œüyŵ«‘±±ìòK5QyMa>3ZLBëy<û]Îõ®ƒ“<Ú‰´€‚yØëW¡8¤Qáhœíôs”œßåêz»Nïks_É%™X=B‹Û²e¿Š¥½ÊfÚðâ×$$y‰ãSŒʦÎXÉÅ”DeÈE›:½FÝ¥f'â¥u~¿QŸ­¿Õ->òcGtüóç­dÓëVsÊ ž #Ž&µ‡6îFè úœ#þl5Ž"GlYòЕœFì:Öá"㳃£‹0JÑimF& ûÜ"‹dtýÂƹH5‰$º6#ª›!åÍ®»ŽKoo©®#aaäi E1½çª<¥#ž´!ç"Œ‹ G«§Aðn¶·»®<'x•th‹_¤aÛ0 Ô(-NPY•Œ¥‰ 6úžÉYê`%'­ä¤–œ×(˜ÃÙÔÚÐ0;‹K2¾]鿯?Ød~ È~~¸Šg£å ;•(˜°E„Ø×“¢—ÁiBäSæp}Åd~?S³wd«ë×Kûwnss'·-üò +zGuÌ)-9=‘bãçÆè]3½,=f³$QŒy¼"¾ÀB»bªD‡Í%vþu%êlÖ ;n»¦i7¶Y¶8ú<ƜՒ2F¦[š.š€z$ˆëœŠ—°L½‰Uª}ÄT¼Û’–(2fM+±q ÅûŒííw×¾rÉ\&²gÒÚžäÊF(cSz’qPš)~g²–F"©UlZÍšVÕh!>û„bÍáTÏDéÊnËÏ×;²�`7¹N‘›ÙÿÏN yþ/7̬Æù Ó1*°nÓ–±KëÅWÄY›üçúbX•l}¿äŸoã~¨2{Ó–Õ¯Ù&ìÉ¡`Ç-¶­.c(¤+óí�œ‡pØÔQ»þ[âÈÓü½‘Ú“~Ô”m+™Ã!À&5[V3´†LË…Ù‹VÅ©ÓkXœä0¼¤&ùh·Ü…±ÏéˆÆ±'×wΰ-ž_gÙ]»ëŠZ>F‡û±D KÛ4GXϼd14´ii®y¦¤RÃÈ4u«[¬yOá­s¶³&³Û¾ð—ÌŽUUÄŸŸ él¶Ô=ª—d|Ññ)#” ­Ø°@'Kn[d«M©ê’¬ï%ß[“Æ‹V‡‹VowpϺ|Q±½º N§ß9ÌÀ"å,,² m d Ì8ܸµÌIl0·h†‹2M§Gƒƒu« ¤EKbVÐGÇéÐÉÅê¹Ü#YoSÇ<¶©\ƒg¯€`”6¥áΉ§6µæ¸–<£cÎiÑ([¤wë%Fÿ—:|jé-2$¸%É}ñ5êOèØ C7 ¸[ü׸6¹‰®[އA±O|ýªþ¦n_X½Gó˜ŠY¢j¨yœù„Äv¡6â6þà/ía¬VS™ bD-EÒ¤™Œ6R* —=߯D驾)›V3NÎ1 Ò·+äPÚ]/ͺ9›³ZÃt‚¥&3Œ Ù±1j4IW¶‰5ç¨ý,G«fÈ.—2„¯ˆ•Íx~ª1Ú'Rœ]rr‹Lëz6ãü6™6¹'hF|¿É} ù vl„2Ö” VQ§ì°+Ot–{%çZ×á¬Ux¤·nuk„º½®Ýº;?x­áÿþIjÖ>·º9¸6 Éø3±8´Cm„Mê8yBû<†¬%ù^ANé”'.¹I&Ü£ËwO¿Üd,“¸±©«¨]×TsLÕTýæÇ^СV¾[œ´1Ak 2LM6>bÏoûª:„ÓËo—5Sÿ¸{‡\çPOòÛZÆËÎê誫õ}÷×ë+7ûùÕ›Ý\«k´OÖC[ÛÎôñ[\ûSËÒúø“ó¯=þsÕÉâÿ.O=ZY_y‡t\+¸½•V7zãj3«Õ¹;'ÂÀ •€/ÑAšB¥Ö—Þ Õ±VÕI”ÿ±ºþ÷òØ7(ó/b-hKÜ9o n–u'3¼D$iŒ×ÝL¤^%vu• Ò*éíæÈ00­üyáòÛ¥Jòi'­`YZrƒï¦À·¦6µLšj‰r^Çìß¼ïÏu¿tå»dª…¸‰tTm²ñ‡_Õ½ Ëß%Í¥ùú ÄÄì¢q±}¡0¥%‘·QÍHSÆö†¸—6¬f uBä‚í¬÷5°ç¥š•Í|IããŒS,ˆ¬¯Fš¦q’Er|ëéù%>^_Ðy35¬?…j¢C¨­Æ‹ŒÔµG‹$›d`5K’q½ë°e›]—Guð¦±ÙqW{¾ÿêéÞô7Ö>«ÝoiŠ÷.l“[A>éK‰ ûºÆž¾ÓZrÒŠÔÛÇ9"¥{¶([Ìܨ7Éö¼[p™C grÌrÐlÛ*à ïE:˜íj¸ {愵’ð\¡õ‰£ ß²ýŒŽª‡ ýéâèå6€Ùž¿â77²°â5,ajõvn齩¬E´Eîs!ÛF=¦¬õÞTõ­*ŸÖQõ_ëumä¹ÿÁøÙ}€©ølEÚ×¾ÖÏýà7÷Áx?*n´œ»Åx]¾Ì7·¥!átÈu‡³;3ì½_ÐþÖ1+Þ5ðV×}IG;ˆ™Ë[™d¯Ìp?…Ó{¼Zd’™c@|î<HÛÌö ŠAηqrÜ6fÇ–Eî7Éï{™ë<ó:¿Ø¿?l_î»~]N«.«Eñ8¹kv¨m2`‹N'Dè)‰(Êä9‘eçjb6+\Û±5ï/,½I É^é[Î/¦Ö uXMÃYåoѹܻ|¾”V£Z 2™U*¦s} úÀÂkK ø½z=üôøé/{?нŽÂ/ûÜ¢Êz~ òM«Zb´´2¤#¦m!TµÕ›çïꟵªxTGáqÀ:7™{NQWÞ)ˆwç´ènеœ™åâÒ[ 29·”Úʰ×eem2Éq†UÈú‹w”ÑÑÆ@& ä¦øÍ?ú ÛÓfêÀV¦ÚÌL4™[â™’Dã]ÚSeR M·Ðú ÜÙÈã] {^1™Lk—£IV»SŒtg9UènœŸf&†H¹ã&b ¬&‹Ãd'/¢fä8$1Cq“Â|W7¸‰öZòòlîo^ë{\ã{Q´Z`Q2nñp-°q"½°¨3×@«C”‘)ç¬â|Ò2ôp¿bC›:¾æ;ͲÜì7^ç¾%ßÛˆ-å®r¦7yx5Ø«À®]Ä-¦Àißë]Њ‚Àª8²4ÃP„ÏÎ#¿x­kÿñ»e߉ÿP/ÕáÇŸ?`fïêÀÿzئA‡{ÎÉFà€½Ó¥aÏIö@Eë ÷ä{Omaý1¦¼¸?lYÍ’øp³têóÊß,OÖ?]¹ìc«ï|gò÷"î'#q"@¨ŒCnŽ›Äƒ›‹†Ï¿_" 9¡EïŒ{½ïÝõ¬Žÿ’Žšf×ðw;7±àºûÀý"÷dAc²¬³­cÒ9ܜؕ)ðؾ%qûâ¹î<¦ãw> ¶Žèø1fJÇ¿¢¦Eu 3VOMcÐ)1ÁRF7N‘zO<m‰õól-Kð¨CPZ,eˆŒ’Å ºVŸ[z£´]{ñå~ñö@þµð¬8à,´ÀÚ� Â"ÎŽÌí2>âËo!< Ö¯ÍXwñ´ï‘?|9úzß+>¶vôöWß!ón± ,Žt°ÐתµÇµ—œä×Ax™½ÎDoö9‘Ôm´ÌÎ;ä_µ$ÿøßyîÛ³ÕAŽ«ÎhY_轡8†£ß¬ÎÕ—A&6¡+ï\«î¦ýÞ½«¿ªë00±µÒl3œU€•bœ‡òO–Ž jnP[¯/}G±¥ÕøU¯7à§±ò›ås·’AY~ÑÊlõËby ¨™ŽŸ]ø–Ñýa³zÏèqýªy¦ñìÀ¢ðƒ8Ûõ2ÌO—´d S¶ŒÎBŸEÒfå"¯HسÉþfá©ÒɬóÓKÒÙz²Y£-—d“H…Ò-C­¸Êµ˜³8|¶I®à­š™ï#Šƒ®EO2 ”7fˬJ|'õ*Þ„]'N×1„m4õ9ÍŠe§¬Œ eˆÒB(a(È©­²qæ®á(}§`{¾W¿*ð˜þ8VÝÕ\¢8yb¦œÔ‚3VrÊJ6­âån·e«´xÓê;×áGt\|ßmnîÁSZÖ© ßà è‚} ?/£I™ÖoîNx ¦ˆ°D9£Ã; Ûï]·Ø±µßµO¬ºö…UÉÊUÉØ‹?³ßµدåGŽø¹'0ß¿ýo«sÏÀ\Ë«XõæmšðUÔÔ ¶ÒQ™ZHD@[: Úâ¸hÕ/fÈßZÆŸØ @¹®…Š«î™ ‘†oÖ( ±£æPÇ¥mÉÁjúVrØâõfï˜oݤ>Ed!_qÓ¢¿škÃê°�Ç;©Jg“ÌNR7lDRº’EòK²>3Û)"oJaqÌX¼ê²ýeå— òY½�� �IDAT.³nË–Ûó®w¾óûÞbö?a[7,T‘¼Æÿ7£Ò3ãÕštBZ8jÅ=Ï„Ñ'ëø¸hÕ‘YA¹ò]–»^×~9V¿§BþvÛù}.õì23¯PžÏHÜ— ?‘ã~‰ñ²……gÍôñ¿ó×ò}= Û£×ë—›àb¥ˆË‘kùÄÜ]³º(¢ŸOÆKiT£.}ç6œ0ÜC™øûÜÜçö¶òS²õùþzÙu¬çZ±Éj[ä:Án«Ñ—·…<r Çí5Ó};ïDÿ¸ùÐ Òþì϶o:÷÷‹gª¯.Ú¡ôtÜX®ýO=~—ÔÞiø”-ë(’jP€a"»4Íôá’zß F¤lõ1ST°ÒL+s[·¯¦ó»Ô*SUùK¾gåjf1\›¾¨´âEs¨ Ñ‚áF:t$ÃÓÑFf³4'ÎÏ㙓œæâ£Òx³ãS?ß2!ŽÖ`VNß$›HºÉ4²âI‹ÓVžÄ_œÕ2˜ÍüÞ˜íñsbr¯‰ü"¥(µ)C«9©Cžªû€ñ¸nó™zƒÒŒU×âF7Ï‚‹Wׂ#ö9fH{Ãêßï o÷—°ÕqUé°î ˆ£G&ŽÜe Š¢ P‚ºâÈ6|¬ºÀ'«5ÎYÁ!׿v·È5®{ø6¿x¸-3·×Š{ý>Fß_˜Þ—`ë$-Òu mÄM©ZaÔä¢!„xíµù»ÆíзšL„ ¡â„–·±òí‚|8Õ‡‡×Ƕ‹&k±4šg¢RÒÜ-›x@„@GGâ‘2пW­ñÛõ…#ôà&áªT—¾â¦E5ײ´Ì ëˆKÁ‚ÃÄ&k3‡‹:·“z繨ÀØâ½*§Cp·4Þ„p½K [Bø±h>M{Q3=“IØtz§í 4}djPYàQðézë®'uôÆm œZ”¹›SÄ/c彦õûÛ’ÓvÝxt%”qHš,`føT{D/2 Àz ¯>­Å«ý?gåÝ…éLuTgaluæ‘×xü]àÍhÔ)îsâã ›^c—B’ø–v¸D¯YqûÉhIö‘JÜãÎùrɵ_é‘»K”’šÊâÏeɉóU à°™¾§Bß“;÷á%Í>ð}Ùž'>T¯/9‡ÿh‡¨!§š4Íp”ŽÂ% E3žn¤ÑñÅ„Ã6@*v²†Ÿ§ d+±vjvùÚéhõ{¤#í ˜+(÷8Õù Õæñ0XûŸ[‡Gÿ´<ñçvúÙ—y›¹—–ìËÅM—ï– ‚dHKRƒÇXÏõ®MŽ£ãæ¢ahÈó§<ìL«“ãj.-)¢ÓØÔ`C/æÇ ´Ì±‡œ¤Må” ÜpÚʼ&¨î„<à ߑ¯€…%ÁþÞÐŒ¡à”›hŽ9àõù‡¥ 丸Æ/‚tRýÈ$â ǵà rD‹»j³íTSŽ, ƒŽÇ-ÓGá=… ø-É©‰RsÇ´à„œÒ‚:Ɒ͗€Wøy~´u˜·ä{ãû6MÍV¥Ï8ú|2lòù0øç­zÏ"þävÊÈšçwl}BþëÂk¶ÍÂ3 7ÑàüÀùjKÊ­Ål!êüy„†ÕÕëZ}¯À“ÎX?¦ã2~fô#­ƒÿ\áGzâSO׊I’+4hâ&UãLò¡zUçùLØf€2;_aû‰R{³Ó¢+®€iÑ_ÍÕõ=Êd"q:ƒiÌžÝD<°Ñ^Œ_]ÍvñÖÉá BfйYñ‚+Ĭœ¿)Š3¢ÚèeH›”U²QEðfx œÐ‚G€/ê€ÓZÞY %.A,©X1"”¹j}íH -­ç°:Jp¥@8¤sÁ§ï]§ÌÌáË*–öò3:â³a‹³V½wÝêÓmd­ˆ^|z°„ V-ceú&~ò]*”¶9¦4*ù[D0E\Ê‚ ±(µ"ž%ב·¼-ò¢³Î j|Ô[5GWRµI ,^ç)g´¼[°ëöIþ·®•ö3Ǭ_V|ñPœ™þ3Û<yÂfÎês6Æ#ì“<±?#cجî‘õzŠÎ6Ñëiñ¿voÍßÛ¾vnm™13;¿ôæP™Õœd˜¸,à¹ã¯vÄÿRrÑÊϯYýþk¤}ÿn±ÿYݶ/㓾"ç÷•¼ÍþÑÅ;Ù2›cá:iã&Í·!9-»¬³ —¤ÖÁ GMF@Lvøá «i‰Ð²˜žÏ¾¦›©9¶E¸Æµø›'C8a™´o;¦Å…¡ÔéÎbãZP %Q}Å œ–rmö»œ-p~t\ãZÉ*Paa2Î «yNÇ<¨Û<VÙ°úú1v(eECT¾iû~ù£ù;~oÝê÷›Yï*jæ]›gµàÑ0 OMß”5«(¬bdüw­¼¿{3dËDfhe¬Œäü*‚ŽùHµÎÕë<F/a7Qö¦?›)}¼^·Ÿ­~¬uàW*³æÒ8ÑéhŠôfõýf¯w&Â<žv6ßãòo<Ê›å™1ZþëêìàÝÂï½>ëýÈ4Huñ²Åãc’ùiTö!lXŧu›ûêu>—ð`‰mרžÏÓñ;WÄ´è¯6ODW"s2»$VU¡´LR}Ov8½"T9œ¸Ôè˜fB*Nÿ맆_â';7Œ2 Ÿ±»â¯ø”í]æÈ°ø¹† éñ"´Ä‘™PRsžš‹V³mm«ï¨Ì®u±½jëÀñÅoÙYøð¾ÌåQ±©q,Dgf5~Â.go&>ª $>÷œÆ!¾‡ëV¿gͪ[cùÌÞil¢ü{ƒ/f?Ü:xüZ—sQ+2„žd´Å“‹£Ý Òàî‚ÝY’ó8–$gÉ%‰9ÓD*‘ä”ãuk7å"ñMÖ¿Ÿiª`ô­æ¼U·Ýäº?xP¿zÖÊÓ6ËUø ‡p{'¸• qåxœD8{ŒrRK8ì:ì÷­ÄgˆçqYÃx$Ô—Ñôìâìž{jð·Bý=¦åë ; hß°3"rÔáÎ8—ÕŠ»Ap߇¥Ú?†iÍs:~õÃÚÿ0ðM%ú,;õf_´Èzöœڋ*Êëì¯O£NcÓ VR= þoLx˜FŠ‘j;2Æ£–dÒ<Ý4±ý¤–ôÄs@Z„™(·ù¹™”æpì‘·ø¨z¿'ÏùýúâÄqê9Ÿ¡eعy SŽÔƒ%ñÿ朖¯Þ$°ÏË\³;HYÑx*«FÁ$cÂVl[͆VœÓŠ‹ZÑ·š!a!`W¥C`ü¸Ç?0|ìâåûÿûWû…_?¡EýîóPèóZßãîl™ý®®3%<øn’qÅÚ§ë&x¦­øT½Å©×ù“°ÅÀ9²¢ØA¢p13˜|ø/õZqìÁ7çËxSz“²w"U˜âˆ0Ó¬giêóâèIFG[ZãEnt&4ª¼÷ŸÑñèSº}ôe6÷èõ®õŠÔ’²”Ø;ÔìÌp&ÆšVÓ‚cZ°5­­|.`™Åvœ²èŒ¯SArÓ‹ÙÕ* Tœ©ÅÔi¨6•@*›¢!ðC G×y5c^<­ÈþìÉ Ô²ý™âˆý•l¥¿Ïµ~á‚Vw•¦ôðìw-z±¦¶4 [\[=˜Û5 Ñ̉£mæv×ÍôŽÏZ5¾yû³Ü“ï}ø}­«~Å…â½K2æ´fæËŬ«¶!Nñ³¤º¯SXVÊÏ阧uÄs:¦O`Ûô:ßx z~»:«W‰{â0­_\vÙß1`¯äÜàºv­ÉS#Ãf û@rT¶’)(:ã¼)”oú|`-øÀh‹£©ù,üøæû?y¼,ü«Î—qÎjÀ¿x(djv«-ñt&Ä(ŽPbÜèº|{¶Io6ÆS’'ç×Âá~5hzîum3³«Aÿ)¸77IÄdFM-ÂøSä^1U°Š/…!Ÿ}j³7M›ÀýRîÉ Î|³¿VZìÿÚé;¬[ÍI+Ù¢æ`‚º.w:5Ÿ¼‚d4'S{ÂÀ¢Z˲ä̉c”¸jßêiKŽRS¦ô`Hà˜ L9äZÌ‹°‡œ¡Wª�oÏVøX½ñ•Ø—Ž[ñÌp'íÐ~ºxÎJ £W¸¹ßïIöí­ºgÁy:µãe.Lôk«S×3Å}&`ÆK;é›¶Åaæ –™ŽiÙƒ¡?ZÀ~Íêüð·ù%V%ã‡òýܖ‚LwKKŽ@Ó«§%è˜ÇtÈ®×øTØä¬U8¸?CZö¤<šÉ”Âá_?èæž~ËX¸»Æ˜Ou¤‰i›M²ìÙL=C˜Ï>ÉéáY‹Fñò ž¨ã¡Ò£Ù—tTŒÏ€{ÅŽï‘bæ†È0:¸f>ëZ1š 7æ3§œ7bäòb‹é_ƒlOvHR¶'µÛäºyŒv‚å6¬æ´– ”+’³ˆ#O½Zq´¦×|OªÔÉ ¹pÿ¬<Y¼Î/~êV?ÿ†Þß—€d´™›¨6M‡œ–©v´JÆœxΆ’@Íœx–$öóÎ[TòÈu.¦iòm ;jEù;Õ…µ‹VýækýÂ;¾Ã/ïËD8Œ&0d†û6YÔ48ˆD­Â¢÷Y«8aq¾a2F÷4GNˆ&»(O[~µ<»þM~á_¶v÷5~ñ¯)p3šl>¢":Sr™á1˜P›’ISÔ œé’£v³áÿŽûK sÄÁ²%§ŽÅo”ÖmYx¨$øÀëÅ;@³ ìVdÖÀ­†šÒÇ Òán.±½£h‰‘7qx1逩DÀfÂô¼JZŠÕ‡÷fÈ&µSIÐ4“=ÍQ2+"z†|¢ÞàOÂ_ òm›Ô_ðqŸ gºš’ÕŸ;óûJPBjz,L“†VrTÇ´ÄqPZ´\ ,v™ ³šB2Æ+yRGчÏèˆÍ™èQ$Ö—^ã¹+ë΄$Ù$@ßBÅ„Q¨’!ŒÓئt£xµŸ§Fï«>zÒÊ¬Ž»qwüÃòxx³_>q‹ëþÌÙèvæ¾ÿ9Æ8à°´ÉSÚ°TËhÀ3Î0õX‰£GÆŠä,HɺÕ{Ýt,TÓG)CÔÒþÖRÈ>ôú¬÷=ñËK’qc¶®=u®Z1Öb¢¥çS¸œ!,؈ å”–|¦ÞâOÂ'­l>Ëk¬m°"§6SVN[ÖÁúïVkÿþ[ýâÝÁ`^<«Ä¹ŠY¢Ï7ãÅg…<ÐųÏåì÷-N[IÇÜ9îã¡kñ½ZÏéxTbÏÌKÍý(ÌÈÒk͉D¢O¢ò3¡Ëùr*NÐL#_&üºY¿Vžp7»¹Åžxrñì—.±_ŸÔ'´dEü$‹Þçrñ”¹d;.I³?Ëx/È‹˜bò¯ª³ú„ŽÖ¿9,üûë]çŽWùùwôMh‹#k “¤°ÔA˜—œy‰ GK„€DÔ\ÚW’ê™tÈ!“ æ¸ŧêÍ£‹âÿñwùÕå cÛjžÐ!•7¹m×J¿kR…FÈ~H,œ³’u«)cµªPlHý: RQ±yo{ÚÆåV'o³¹ÿ÷Ýù¾³«’ýO‡\+M“±˜™4W÷Òq?3ޏNsªÔNP˜Mì¦!µrç&çÉ¥kN]‹mƒ8MÉÝÙÊÛNWåÖÈBãíf: ‡ÿÍ9Óˆs±,µ…u’íÇø«5†Tx‹ÿ6GÌH¯ŽØØÍØeTqáT¬t]TÄŰÅìΤÄ_ „>Ÿ Û<†<­#¾¤#ÎZɲdƒ…«-žŸÍø­é1òáϯªó+âærmÚâè’1CRtw½ë¹nÚ S.ÂeË™¸(ƒ†1Hõá0àãõ&ÇR¡u/׸‡¤Í«ü<ïÌöp_ƒSZ0H­ =ñÌã9-‘zk³Wrð1ÎkÉã2äÁ¸ÝÍãÀôµ}‰5«›ùe M—…êIÿ7÷ "tÞéº÷N³ÔÄ#u<ÖT&u†ôMÛ+’¥¬(£MõrÞ'˜·0žµjü„ŽŽ¼ž¥ž±òÿºÝÏ'u ZR[É­Ø&°"Yºbsw‰ð=Â8e%O؈£aÜ\êG€M‹ÆÝšqº³_x8 7K÷3¿yƒëüÕ!´¤EPjÕËî®–¤ïIΪä¼ÂI»¯ÛF¦'ë8,¸uÖÊaaz¬‰nƒ4_uBŠhã˜OùÔH !7G”¤³†‘ÜŒàÙž‰þ¾îĘçÄ»ôž‚Ë’ñ§ÕE ›œÓ’å67Ç~‘oóKÜ–õR=.‘2tÌ8‰`‡„¤¦xÿbaâO‡­ú¼UgîdñçKìõ¯ÏzË[æQ£™ÕÙ0·'*OfÌái‰Ã‰£$N¢F#<±Wž]+ g¬Úz4 ø¨l|â{[{ßPŠñ¬ù\½Å9ó ?ς˸¨±Fµ >T‰ŒQè'ýÉæ¡iŽg盘EêsVõÛ:>ö¡êÂçþI÷e1s‘ ÓpYg÷¼2ŽÙdüÏ�e]+.XM©JG=ñ,Kƪä,ØU‘KF å8–$ã ´8'%'¬à¢Õ÷ÌãŽäÈvˆá¬0ù‹jœíÕI;KZª­šÀ´Ms>MYÏ=ìMò™‘ï ØŠ´\†[ÔôÎ ÑtÌÐjÆIzÃ*×!Ÿ¬·ø\Øæ„ŒDY`;ú#Ó¢†Uû¤5Sëo‚ßdû_Uç7Nýn{ð­}Òjà)zÒ¢ç%1"!DÓ 3ê�W‘1/Ž-Œ*(§µä aÀ³6nêk[„£'­œ¯Ôn¹;[¯¢ˆcÕåì¡|#pGj˜_ñK)R‹)ç´f ÊYï'6«ú±1:LáÏÆwÙ +Ǧœ\”ì_ïuÙ½ù¤³*:Àå"5m\RˆÊM”ÝÇŠËØçr–Õs‹ï.>ËzÊvʨ+žÒÑÆ“Z|êNß{"ÃßÒ f±fÙuž.ž%òD¬™Ù´ "é[àB(éOkdO(Tö|öî–ïi+«‡´¦'þç^îºßdÆMµØ„9«6¥sÏ’”$µs¬HÆu¾Ã)-¨1–ɾy@xrˆuZ# nÝêSMgT\6¶ t:"´-Š¢oXÅEæp,ëT ø­lçðÕ­”—Ы¿.Ö»çî@-ðšúÂ$Û#Ö¬àG[Wó­Y/sH)BâÓV„fPu“ñT¨¢z1×É�}JG#ÅžžÇ}à[Xügg´$8ã`">y™6×Ï52*Œ¶-çè†h«=ñ¬[=?c;lbŒžÑñ‰Mêßh‹{ÃÐŒSZ±iïÌWù¦l$çH8Çs­k³n5‚°O2ºâÓ^Ã(Z§¡Õólbö�×°•Iþ\D`Ü(6w Áåù¥KŽï¼V<i#¾Õ1¥+’q­ks«Ÿç6'Iâq§35PAX”ˆ"µq MiãÞÚÅ?]Rtç8ªÃx6Aú—:ñY¡ç9‰ícû\‹%ÍVÓBzãØZ=AÑö»NÞ–ìKºÍ¹Õˆ¸¿ÞäOfžÑŠ'uÈã:d=}ô©³™!OÕp>`sLûÑ·/ÉÖ¿b¶çW¼Õ>O„¾\ç:íEËè QpwrçªÄêÓ£%Žy<‹ÒŠª)«9fÇ­hžú‡Gب²’ û̯Wgß|•˯Ñ�×»«®5‘kÉšU<§c–$cÅ7Tì¦7Ða¯d쑌‹VñC­ý¯ûåòì…£VÔÕ¿h"‰ê¤•[GtüäïWÿÑßh]õþxÕãwÙ´Š ZEˆÉ¹I×Sº}½ÒýÒbYrF¦tŘ<UFÊÔ,;±îÂI+Žüb?cM+@bXeíɼ¶é™6hò5’CI*z3L•¢gÙX—ªøë§ÂÖ¨‡räÿÛÛ³•ç†([‰|ÔJï?é/G˜!Ìá9D‹Ã®Í–:È«{’ÝWZuªÄZ#S¿FØj Á,}¯F™dh‘ÇÞH ÉÙërö¸má±Þ YnÛÉñ5Z³õ•îôŽ-}‡\sI@v>ô©,pµ_@.þÞó?¿UÁ´<9›]λò½|_¾ ¾7m9Ÿ‚Ì1è˜Ò—Hf!‘cF4NäE3AayZËÍcR|ú©0úwø…{7­f¯åd.KßjzjúÕ"eAN`œ2±Úf4`3Œ±©M:LÈÃN26¬q|g¾—Wd«±8 ÉÞš-³èAGmÉ0 |! 8©%g4²Î‘³: ”¾œM(`¼*[˜¹‰ Jœ™øåw[ãø ìÿcîÍ£,Ë®òÎß>÷Þ7Ä‘9WUÖ¨*M%%¡!H1dìÆ˜¹–mÜmÙÝØ`–± ½pwÓËt# Û m¨mÙxY’JRi¨*!ª1kÌ93æxó½÷œ³ûsî{7"#'© õjåÊU™‘ï½{ï9gïýío›Zò˜ïó1»Ígm‡ È"ÇM“ŽNaDX’”%ªù¾]%%Ãè  YDXæ$Ì^^ÑÆœè©lø /ÙÛƒ‚Ü�ùE® )•XÑO“p ~—-µ40GRüÉ"@×Ù IóµéÒÜ|ÒüéQ´¸kú!ÿ©\ç#å&'Ý€õ@¤£ŽmìxA ü—9Œ¢Xvõko’òUÏù}U¯_=Ï@þ`ómIX0­ÉÀ‚–¡Ùåv%~ß�‰$ì.ÚêÙñKïu°£hi¡\×rói/üÃrã‡þnóØ*Sò¾¤ƒåˮǓ~@òr3 C±x-ÇãÂQÓ`UKúêªßAÓØ^seW¿©U5ÚP»>Àß?Eò~'J?.ì‘*‡LƒÃÒ 3>jÇ¡o€gSK.h�‹&eÓ[Z˜ûÈç-šíÙô•ao·!ÉÂf“1½Û1QGÃ!æjk5ì[t •®ã¸v5Óêší_ø~÷„o=t«oýÛW%Ó?´®%‰M K’Ž É=/ )†&ãm±¦%_—Ìòyß½o¨þ‡m'"͘RÒÊ«‘ÃÉhE!ƒi$aº¢Š+,I6–ÇKãÑ*¹ð“¦÷häù’€né=RbL"ÒØñEbLjº4ñ8o47F] ’ÄôÕ–ësß8¸èû£Ú û £gà±ü”{™4NªúГñF’Ú6öAme|€ùqÀé©cC-OWN¡EH4Œ~Eã Ø~pZó³ëj{Q’ïLEX’ŒS~È\/»>'¤Éë’9n1ÍñlX…Q¸S8®¦F¬üª¹¨]{"£·¥s—æ“ÙNŸÞܬ÷¼,™ ?âG¬ºK’2›Ì„‘*LÄ€9ïG<å‡\Œ½,E/ê¤7µßž'„ïÊVì]f:d¡*ŒÄ1Ô’¶z²ÈUÐØóßõü3“S>ç3¶ÃŸÙ-žŠhV ^ye2$&órc¶¬Ž÷V`TNapLÆQmpÆç¼ÚÌð×½¯ƒ}Þ¡[>ôÃqO\gÏOdæòÂûʯʟu6²C ÐskCÍC>(}µîIçæªuǽà›^<xËÇÊu~³¸Àçl‡Íq‰0o6¡M³Q®½riÃà;±í‘sƒÚ¡/jðóÀßj—hßÂM`ºa,‘«*0xí9>c\;°¯ªAÝ2R³áÏúnB -:X×òâ-þ¯’ýlú’³”\t#Îꈃ’ñÙ$™ {H-FCÈ>ú‘ ¾l2¶ÕrNs¾ÖÌ|ÿi?z~¨Þé‘*�C\·‡>û´ÞgÒþ†Ii & ’剞·l©¥‡ã?Dƒ’qGÒ¦‹ãRÐ:\na ñ§÷é7øyIó)iœ²" QJµ$(O#Bèþp„îÙŒ\da]QÇ´þç´(OúáÆ×êìÿÛÇýÐP•2Ž™RU,qÄÃ×þi aŽ„ãI“‹Z0TÏ雽áÁ†Ê¥¶dÝYÓ\±bÈ›F¨¸†µa• ¹ÓЫÉñ âï‚,JP ®&[ö$ÿ«|ù¥ï•´Ý€;}+êÞ8o²ÛÁ4’ªÚPa¹ArÜ ´Ô=;m’ÿ8£½#™yòÑt¹»®Ö°8ÏÏ4ŽŸY¨f/¥š‘´àv¡"º£Té‘‹ÂÄM°‘ÈÔE¹fô/{«¿ -»OøÁ#_r­_zC:û»ê8ï žpC>ã:Ød–;´ÍA²˜ü†Š¾ €)Zxö &fÙ—í‰ÛÍTùÊdn„’Ÿbõa‘Œ@ ˜ Sí?kŠ:UNú!ê€gý°BD„y«jûV×|Ä4ÝÉ â¾ ZªŽvL0h cE&´«úd‘}{Ò ù‚ëŽpÒ _àGŸ´;G¿=;ð­Ë&£M2ök41AZï´{á‹’q\š<k†l¹’Tä­S$Ÿ©^ð¡¿ž^/Ýi˜¹‘bÊD´g–”EI9 =ü²2DwŽ˜¶ûüü7¯ üºEyGawø­ò"µÛc›À£NdG çѾÂh`^{Nýø¶bË£®1ý—_ùýxó8oiÝÉô¤×ªA\­U)c:p¡®ª–ª'QÆc``'7 šÅÙ)ð½5-7>mwž}wvàö§Üˆ ”‘Œ×¥3,˜)H¦¢Á§½Ç_ð‚ŽXõ%m1,0#†¾÷\ÐüöùZ‚­SY«ú\l|;j×wÔýç µß`ÔÓ””E‰!Æ[6uĺãÁÏ\=GL“¯ =u<êúØåÝl']Î¨Äøu-}KÒA!†\=G%õ4â�xÕ¼—}Y¢(˜Šj˜wPƒ ÷ë,Ý=¬�� �IDAT‘ùS:½à‡ON;ù£¦õ};X*凱–È$=„––4ãiÑ7žwHÊ£¾ÿ#ÜÖ²™i~_ó–»-–¦Æy5µ“± [é”D§‚-oYó%«Ñ-:A†{¬¨ö5Xþ+M8ð½¢ÈŒˆ¼E•ÿ¢xŒTs[6’ &O/güööÜ?û¤v„þøíÒúÈ9Ýé|ÆnûïH ¿& í¯ì{9Awu}ÝØÏ2×ÐßëGB±ÇÚ‰Ãá ÒLÐìë¿q�¼¤eþ¼môpjüã/¸.Ï눿–âlÝ ÉLPr=ú¶7îY$ ƒ ±h&ÐÔ z¼'f%Õ§m/yÐn®œöCn2S! ”3•‰¸}œ{,ðôÕ±îKλœM_V÷ƒ>ˆ0׳'•’"W76çž—Œv¼ßmµ$ª¡²¶üªà÷¼òœ¾Õî·è¦Å—´¼ðuÉì£K’þìÄL6¨(‰ìîÿ¹8”‰p@RŽH“Ó¦`è<rkOÚȬ®?¹:ô©D*gãrDqJLµëÒ“r›iÑá]f‰]ïÛ2Éžù_f¾ö`»§£ŽÒ{†¾Ç(VùØ$ð=dàs<UÕFrƒî¶Cª^ÝL¡‚v»ñ÷Á¢>/jð{wã˜YvßDuQRHÇôçëÙUßv•?”µ¤w*+¥u;=õ4Ä|ôýŽ¦Í«ê,7uàrJ?bMKÎkÁó~ÄiŸsÔ4øZ3â¤tq<èzìxË]É”^²åA&ª »TÉ –¤ñЂ¤ ãæÍQÚÑA»ôž9R›`ƒ¸,Y€€M‹Üî0Š‹wÁ¤œñÅm:aš5jìKyU2ççMK§Å„'“ŒÛÒ“q½bZçc`Ü #ã”S¿ºŽé~=2xÆìg\gsF’ß>"ÍïÞR»bUY6Ž%Ò8³¨ãM^mŒOgÁ¤œ Å–ZžóÃ…·§ó¿¸’.>„È}©&cÆIIìê®ÌÙ¡ôÔ³¦kZP„ ûŒyÅ—$«S—ßk@goýƒq¯>ÊPÇ`/“JWDÃȹ†ÞÇE_ð‚~ ÄÿXsÿ9?ê}Ñ÷ÌkÒÙ5`e¬ñYckh˜ Aù3>ç”±ƒãd3M–%å Éh“<ˆ L[¬|…ÐÊíŒÞé—NeÈ?ÂÿÊ«Í4/k¬Ä=T;hhFw=+ªü’×¼ªø.Û«}—~‹™ini΂d,$s!Áõý˜àÖɆˆ>UO© •É9�×µ'þIëÍѨ_Yɨˆ)a¥fûˆäx Ô8w©%˜*ø”Ö?`0Ä~dxòøM¿šÝ°cìÖf†ËÚˆD[B⮪4§|~ S„ʯY«þ®ýhÕ{‚Ÿëä™Õ´CÉ#IJâøC{ÿ+Òà•É4ǴɼIyØõŽýpëæc]µxgÜi”‘íp¿Ûf5ÀÎO¥ðaô°²:šP zƒ=oPû5db¬^·Lú˯ü6øA ?\Ñq&oohU¯"<æ&.èTî U¹»åQ«*tÔ± )/Of‚ÂIò&FoiÉ™@ æ4øÚl†Û“Ù ”â æ|lcI¼pÚÀ¢ŸÜøq?éI?tIÒ:=c²ÎŒê1ÈUJ K’qá(,=ÇD#ÓG˜`¤ÊE-áV€¦@C'pxU:'mÉ’ Óĺ­'65Œ|OÓNñQZŠ ©¡‚F{ÍÕ Bý¸ÛÉW¤ñ´ ?z_2û‡©5—6 ßAbˆçŒ/èâ8, –’Œ--yM:Ígm—܇ú(@ Sõ6ê#^þ5œ†!æú±*ˆÀy»{q½dz|zðoç÷½ ¨€ÄƒYÕFùîš]+À߇q„NT_×òWøaž âçùÄ«2ªcì¹rlhɳ~ÄyÍ™&áÍÉ<·' :OÊS~Ȫ/°x Ì\¯ÄÙ•àS~Ø}Aó§÷¥‹Q¤n+6çi?гŒR=mBår³irsÒäY?Ä©®d˜)‡OkUßxO¬HCÚÉTk^¦‚Ê’DO‘õc•ߪò¥†‚¸èHË›Áì‰èCâELW`ÅT2žL„Ùm-PՓОQ¥hzek.Ø¢ m‹îŒÔ÷'þÄ—?T©AÕ÷É=x§Jß;¬ê©(WUÃkõýÌö«_øV‡ú瀷OœUê<ÝðÙ(Á–JHdR ä›Ì´Éñœö9_—.’`8hÚ ÊŽr§Â‡üK¾¬ø·hϽýP©êW¯–˜Ô ’‚Ýæã/š¼Ù ¿>˜Ÿ1ß×<2;|ãÙž«O•&“˜6*<¶#4A”zÃsD±¦ež ' &?nÒf§¨œBXÈ"Icž”ãÒä˜i‡ñ±ë „<½0ßrÀ£ÓQ6k.–ÖãŒð~»éGZlo{ÿ» ˜¿."‹ûcvAx¥*FKr|èqU°ÒÌ óA¦+«mtyÌvyOfMŒ+1£µcÈlo%}¹0’Ö+÷¾§±o¯ŒÏއ}·ïð¥Èß~c:÷ ½J-¿Nõv1ÀßmÚ2Spá _לGÍž$º{ëØMâr½P˜|N3®‰VÐÁ”7`Ãó—ýʦª{Â&.$|ú.ö¡¤Òu>T£TDøoG-Ïû|Ñ¡oÔ­ú\iVl»½««›³>çœôÔqw2Å“…({'•_j¹¤%}f×èÎWD~á³®c³ÂìüxãhŽi5ƒÒPŽå%eQš‘Èd„)IyÏ1irØ4zÞ[×òLŽÖ äd¹Á“©M@F yÐútC4’Ù®„. ë²%A8ÚF “Z•qÍ=¡«î"Õ °§2«ûµ lÄò² þÞu“dz�쀬[tÍ¢äðï LŸ±7~ϼ_= ¶ÄЊޡ¢˜&^Úµjy ¢U‘“Õ;»˜\%ã!§èL#Rãw+# «ŽÇý€sšsI-÷$óÜ—3 ¾ÇŒ–ôñãyç¾zºØŒÝé”Ù«UxÃZRoEíÅg¯{›sÏßfZF½_ÚKÞ× Âï“Õ4b&3- ³&ˆ$רSuÆO ”Z–‹ÒØ<˜LÿΜi �ãN”ÈXpù„´8f¦‚ñ-D2NŸK>g Ax×zO©¾Á§B˜™¸ªæ;çÝ`Xxûá®Z†>G]3úùÞ‘«‹Z˜‘*ЧPϨe‹±‹/ &™Z ˜Ç\G®,õŠŠùW&*ïóg{1ôë©úÆë9?²¸Nçq?øôiüË9IimÄÄ $Œ,d·šV|Ò�„1,J†b¨eÕõéúA¼oA•òJG´£²Ï’d•5Tö’Œ{¾Û å²âÅj°¿rê°~@î¶xÔnð Ûæ/\—s~H_ œZDmpB‹ 7Õõ÷ñ¬† öZàøÿ1sï+{ÙxJ%2aÉϲd¼!™ãÉ|Ô‚|Κïó¸ëó¬æ\Ђ<2†úUVÎô„™ê¾>;ü�fz<ç¬ñkÎJzYšVõ¬W$©ŽKƒÃÒxˬ¤ó&ì‡]{⼎´ð¥EG¨ë£n€ú"콫rId&6¢¬[èЋ°Ûmüš{©÷›á~»]X¢«û&²wPPÇ2‡ 2”I btº5Ä_üŒÝy�<¢#aÈ}o’#µ;؈ ‹’2GŠ4Eæuüª¾©¹ÊñÿÆxH·«þ2í\-ûHª õT˘¤U=Í-µ¼>™ã»²ƒaŒÇÙE£JfH¸+ióéÿmãÈùi’vŠT³z›À*p8\Œÿ¿„q0¬?§¯¸Ïÿ¢V~³¤8°{ND/ÃŽË1tò‡ÙW*AÝ#² [V—_Ú«‡ã¦’©Ózj¢$+ÁABCœ,#¬‘üØêG#¼F0¦0!{ªL+À©=‹Ht÷rÓz¼‰YËÑ•æØWlÒÑ1{6†‹ÌËLƒæ‚$,JÒ|ÖšºOð[ÓBÜXsPævÍ]W ›|ž„N|«›—ÜØ ¸^Ô²ü‚ënüg»ñÉïIWÞoD¢iiø´„‰®¡W©S\Ô!ÏÙ‚BàÞd†y CU¿p¬l±‡Na˜‘‰ yŠ,Äø—\»Ozwp; nÈsvƒ?±[<ëGxUŽ˜w™6/K¦8Bƒ,úVV}Îjlz¤¾r°¸½IrЬÐ]ýECÅwÆ…[¤Å¡$È 3†ß$לmµl`¹è :Šwhç« ~ú”ø·5o)HžBó·ã‹Ðïð\¡¼ÂÛ˜—ñí¶N˜Ì2`EË[vãÖölˆ`ã=qÁ ½S—ëeÚå×ÞID$’¨3ºJ »˜¯º'Ìöëæü7{ ›µä( ’†qõ}ª³1ÜΗ !»Æ^Üðe×¢ŸmÕü»xFjÉ¢ÃC3ž‹Õþ΢šÕŠd,JÊí¦ÍS:<”¨Æîîû]‡ËI"ˆŸQ‘H§ ²ŒYÇ«^æ—ª‘¹»,oIæyy:$ µÀ7Dý0ʺy›÷ê4Ûj9 Ù?ûÈÔ«~ú½ÃÇvÕ­ ñ;6-º¹§Õd÷!´ÁW™¬½¨Áo.ÉRDnŸ cïG¨ˆwSt· „jtVPtJ‹\Öã9’LHT’J}õL©'«1!ÇD�™ˆÐÚ*(FÑéiI˜%¡=.µœ±;ûÓ†!Ás²°Þùs&ýÕq(A4j‡î¹¶eJIÆ!Ó TßÌYM7ùœ Hºê¬ŠhèñÀ™}*癉ßëjó³Z>—ˆy¶)É툠J­º P%˜·Å0TÏ—|?²[ü…ë3/)ß™­ðfz¬Ü^ÄÍш¡¯‡ã¬/œ¢§4¨@¬c†`:ã+Uà—Tìó ª7W66Ï–ïð»Å%þØn±JÉÐ;Þ”ÎS¢A* 2€è殚+¢ìS[¸9C–·ÕÝÔ„¨±î½E£p|ΫešÃI{’z©«Ž*J:C/‘Qè÷=¥á ùª_\±î:Ï/ûKª}\‡Éê®ò*#ܦ-Ö¤àŒæÌJò–)MµØK¾¶'6µp*b'gy]ýj{!L7cB„¤!‰"„×½'fL¦Û®(¶°Ì˜Œ¶dQ4£î$;¯¾]"&yÙKÈ£X[Zæ]ü)¯²VâW*²LŽbj²7Fd\e&QL~Y¬˜Œ®w´TîÌGjÁo¯dÛ•ÒåD>æØFC¢^}²xï÷­¬ç$‰®•­[bD˱»HÃMÒ$I¨†á™“ä×îŸ~Mç¨iüâNúçt¸±æËrSËÑNðµ/vÐ{уŸ.½G:ªmoš(õ»ÈÚ ª U_ÃW'|ÍoLj)˜U@ÙE‘±ïA÷Úd^æ0ÓŠ¾SŰ¥%ýˆ”Ã5ß¹kIôÌôé*ægªÒ.P3N'ÙÓXÊý1ŽŽ™Öç¦$E$h˜j”«:(ºkø<\û¢¤ÜžL±¡–ŽZÎjqW®z&Ç·|m±ŽÔ‹EH²² 𸎑UÙÓpçòäá+yùsš—Ù:lDÒ÷/³IµV5ÄW*!c¶üˆMµŒÔso2ÍO4ŽðÊl%ÊݑמuJÂdz~ÄŽ:š",ÒUǺZ6¢n£†þåK®çwÎ ’£¦¹ujÉåj·xØ÷°(sÊHîá誣% i„;˨s:Òø4î‡)1rõoX0Mš±:)q(3$ÜiÚ6Ó¡ÒóAž¶Tu5Ãw¨§ç-›¾¤+0ƒ<ï‚zÆW}?w\§,|ùH…«‰"ô¥xï/³Oc?wÁ¤,ù”  z|^’[†êNç“1 ¤§N¼š)*æ3R›„»ú~hGô`Ž‹’b›7rmná]’#¦¥ÉŠ™ •µ³»ö\uR§5¤ËÇvH<’=?êßÁ¹KZî á÷ú3°$ ˜´YCÿ¸`ó¶I8d2ûë”Ügf¿þcnûOshù “¼:¿®¢ö¢‰âO€ *4ˆcq ^ɵz†±ß ÖRÆQj‡fõG$|#2çÐ_ù·í»ØPûë¿W®þÑ£¾ÿÈg\gã)?tWHÄ_BÁ‘² ¼³îåÕ§d[ .ù‚,dI �•êzp =‹>žA –oãl’¢W °Þj¦$…%Uÿš\”U,;›f¼ñå¸Ò»2"Qœ5c.Ž/dÈ‚ónwÀÛ€ÿÔnû·&.T°’V,-•ËâS•L–H™3 =²õ›Mëÿ®\}ú¢ëy ª8fÚYSÒùš¹ÕUAÊ:.\éè¤T!"Ó¤º{øU®ûÇ諪ýG\ÿ¡{“i†jIL”*K$dò!ð“ßIyK2Ï7& O¦!™X3ùÀ€khøÆm1øX¼&™á€i‚øïÓìàãDéØ1¨öÒy¥rhLhQÇI?äTÔ9xÆÃ#_ð½©wÊÒ»¼Â%-xÏLìoÔqZ žóCÎi¬6ÀQi.žHçÞ:&uÝuR‹"WóaÑW< 01ˆ‚ÖyŽ[�…Ö‹á‚¡ÌϺW5o99'³¨ŸŽPu¼C.+…`÷s ÒÎKÁ×$³<ìºoÞÁ|¹ÄUÌÅÔAš³°wéÊUÎÄ þŸ‘„æF<¬R.Ôg>{_{Oˆ‰iæ+›•)í>SBU„‘(nïÇ}G©¿ù¾Úºg4Ï15IHcïm¢UÍ®^©DGÃ)1’7'-¶°t½cE²»JÕ³#ü” °ªþöíg†!w5] ÞîÎ¥»ß ’¹/c©ÒS7V¥Iã¯*1N$ ƒ›[%(ED$†¸÷½#]xß´3ÿlN’ËÙ'üpÄåc ú’ ~ I‚¾lÂøS,%¹Zv"#}™Œã¦A9V¡˜7–k‹ ÎÏêèEñY…m·÷éÇ×aÓ£¾í¤¤Teá°i‡¡Zo#ôr­|ã¦%êH†¹§ƒ‚<ïñ¾âÉŒ6$Š˜'€{jË~ wV£j²7%øÓÝjZô‡8XÕ’cÒøîþô†–—ªlmJR—‰¹ëòÕkóòªL«aJ ;*3•Ö^ ZM¹^!¿Ú‚ëb‹-ŸÿÅš¤O쨽§êÑúØ«2ÀP-m‚­U©ž’1+•‹µ‚æà‡8-Æðs‚DÙ9í¦ÅœiGÊ;jÙ¤d;f¼ ú³-ò‹ï–Õ äå“>g+™>ùÔÝ\×Ršæ¿,ÑûÏú&LøáГ~Àƒ¶ËÓ~PíõyI Ò8¬2Òû«[´3µ»‡ 1ÃG¸¿¬9‡Ðá‹•Q°\õïËŽ¬ßž4ÿ¹ƒ_猱PØÞ[ýMK´Ãò¥ ^>KrÓ@ýé":‚,›†8v-RÝÞWØo–·›œaÍ—÷ ÕÿEWÜ®±'Œ$˜™D8^… ´Ï1WוÄgY½I+J€5%¡8 Ó€vï­j¹©~õh5>U][ts÷µÏ0‘¹ªx–$åViÒËš)ù[æÐ÷ÿN¹úüyÍ7zø©È_Ø;¿¨{ûÕFµa�c&«º? ›]ÄŔԱ£–Žº±炤ÌHE^ H[º« ÍHœ`Rr\šÿd9ɦOûüw×Õž]Ór¸‡ä"¼Tz~Šf‚Þ;éäe—AÖkÙd¤Q÷²Q 5«²eÕåþI9nlx[3ÄU€KŠÚý`D}I$�,HBËLÜ#ì5ª>;ÖÔè‹á«žÕ ×pÿ…ѳú#›ÊžºKÓ$÷ê¥6Â<–q+ãf<.M:ƲæJ^“ÌÙpöUugst3AZ·%ÓxÓÞ×+©.˜ZZg¢òû²k¡Ióƒé�/¾‘gýÅy÷ri_,о,éïæÑgQ2Kæ*ÄÅ@[Ÿ@,jÇgM›w}p¥îÓD˜©üçÔò”rÒ9üáº/=ØÓоu’«8q»‰ô}`öåò÷žxã¿o¿üÕ~t]K.jÁy-¸às.ú’3:b¥³<ÔE{¡—¢Q<¢Ï–ºñ˜ˆßwmÔWMuä4E˜Ö„k_Ì»pRGù1ßúâIk"s•lÌ.YûÝÉZFÐ=lœÒœ{Ì4¸Þ×íàó¸õÓj`Ô©ž˜„'½jÕgj'Å”ŽšwiŽ˜Æò‡íæ+Où|u€kúkì‰ÐÆ×…‰»ßå²¾_5”Dä¥Q�fÍÚ›j‘õqÃBÙ—åEXYjÈÕM¦I¡Ê¬æäêùGÍ›þæ¿.ÎuŸóÃíþ:ì¾ÆnvéÕùp¾öû@¢ë)?‡$ã6ÓæVÓŠ½Ö(ý&a-HêhIÂ,ÊFttÙRû³ß•ØX×ò£Öé¹-l%avCŽí×^_mݧ>u¯BCžÙõ9N=ÍÈFJMe½cÇ,@%+’ñ5É w&³´M›éèÕFå‡ÙºÒô­""X1¤’°`qÇ—\¡XÜ´CïE”u_rI Ö))‰H×x µtNÝS‡Äáå1{5¼0vFÖÖ|„ªZ2œ'ùöYIV˜ž’dú˜i/ÏJö×jdŠšlÓî QÏ{=aö瀤Üdšœ0-N˜Ë’kbZf·~¢¹á<ôßÛõÑnðÉ µÿÛ£®ÏöË)7bÛ[ÎiA_id‚•(;êèãé©§«–-oé´O+ë§&A2jbléªe¨Ž- ³˜Ñ°÷QEó—`ÏOd!ÂÖ‘T2à0,ÕPu©0(ð›?0|âX‚¼}C˳¹¸O»!§càò&懸g×Ôn¦rY«6¢SÊó~ÄY-Ææ¿•*‡«­—Š‹–J`Ð6¢ªê‹yþÔn{g’K¡Œ+¿ý>FjÌ ÌwWâHË´$o? éñ6Éì”$ÓMk~Þ´^ÍX¿”ËÔH®tе0¬HÆfŠ;M›C’q“4¿íÓº{žt&ŽÏ\mOª‹#½¬ê¬pÕ+¥D„vdy‡¤pÿQ‡ì–·êwBàsµnÃn4©â/Ʀš$ãö¤Å]¦ÍAÓÀÀñ¿×8öSw™öËçH óõþŸÔ!]#Â2‘TëQ^ó -QVµä‹®Ç•›|¨ÜàÃå&Ÿw]žñC65�¢"¡ðpãŽvˆÇM„yI™ŽöS=õ¿ôcÙá×5››aoM±¿lÛ_%ìéÅà—å8åúÜ!)D‚ª*•8wåà®qANƒÄy0ÔÒUG&†¥èVmµÈlè¼ìS™¶ÉLcÙÄC3LåLtwÿ«½w>jonªå´æ\ðÁÿ.CÖµ>y}Å~!¹QýóT‚ׂ«ÓD½E­¯´ØH"²"G¥AGß.ÌÖu¾~CË­iº;’¹›s|rÈ’ÄÄÑ¡bv`+~J5¹()w˜6¹æå›ÓùïûµüüÙ š¯Ð¦¸e›ͤ>åvü¬$›§ýèwîHÚôžicè㹤9+&#ÁP¨cMK6µD4@Ê=­Øü^4Y¦Ý[j¼./D×n˜Yá¥òÆlxþÒJ?£~¥êû†àЛiˆ!UIŠð0K`èa§ÛþéÑ3Ù¢¤ÿôÕÉô`Q³7$†£©šµKZÜ\ˆê¹"óêC¹<eàKJ_b°<æ|Úîð*3ͦÍrLªª´¨1æüê˜)¤c9ºÊéEI&ôÉŒ:d„˜gÛ÷²2ë퀽ÕYSmþ¸4Ù0%s2Ç£~ðÖEµ«3¦é¿.;°„¤?0™{uã¥ëö4§÷€0cèóxüÀ–ŽøkÙ2³Û?¾(içy?Z[W»ÑÃ]iO0[ÿ„Ž- <ƒyIÉÆ(ÌäZ A¥-Itµ€Z·þj‰Ñm_ön’ôÓ ož £rYp­ŸgIlq”Mcȼá4#.øâø÷f+ïú­ââZ¡:…¤þ2ödh§iãÊå³…WìÄûÞUÇ ~Äç\‡ÿÏ®ÓÇÑÆpØ4èÇÄ·@i©ÆÙÅZòÿ¬‚sç$á4è‰ç¬æœ×ò‡¥ñ.R|<Ç®Æ3«îÛùU€/bðS@‹.Ž—¸¤9G³H“D'†ÂåX¦1&r»•<Ê>"ãVÓ¦TyUýT‰«/YÌ|CãPkVšï‘Š2 ¶û½ÝPPø¯‡å¼qÚØŒÕ¢Âšß½ø÷»¹zÆìJ2ýÅ t¬”ò"ëýdëË ©`žj6§ÂË7Lû½Geav9{þÎd懂Fi¨ø¬:rµ4#TP]CRFo¾Yn3mšjXÕ@úÕÖm?úËÅ™ßxζ·Ôn ‚–_]Açz°tø°ÝÌ%]záû“ƒ{[íçGêyL{X…)°FYõ%ç|Φ–lD[§åfiòJ3âɘ•¡ðAwQtBM¯šåm F¶‹’²®¥-^‚ê.Š  ‘Ì% p´$Tù=üR¡jÊÀÃÍlwqy®¾·jË{ô‚ƒi‡nÅtÉ#â>:ÿÖ§»Z²é Nº.Ns¦ÕsÁù¤ë°­%ß’.r´ØÑ‰äy#Žò(Ãè+·¥%]uãõ~Ý8×u¼~aô¬þõì¨. z;²û¬Õ}‚T}OÌKÊ-¦IÇ@Ü·¾Ì,.®¤óg_,|OH.LÜÏ_†Ÿ",HBbš4TXõ%ß›-ó »ó³·šVö¸|ð”Ïû´¸lOXÔ ,'q`v€ã ×eË Y1 S’„Ö‰z¦c «»Ù·#²®UZû-¡?w]¨‚~Õ7‡äKSð�� �IDAT{üsõŒ$ FF÷€Íx¦X£l¸ðŒÏhþζ˜'e•ËÅŸ]ì^ŠÓ¨‰$”8>¢W'¹L´w-§}ÎSnH7‚ðVŸð¾3;pСtp´0´|‰ODÅÆ @œˆg[J6|Éë“Ù¿Úç—ºê¤%Ýs 7Ü|т߶·,HÒ[ó'}ŸW'³Ü”ÌÅfí�íVöB•ë8âÇ‘ZŽ™&wëœ0­©º­;Ïøübg<H#ïji¼¥qÓ«ÀÿLØ¡—x5àÞÌ©Œê§µàœ–äáþ­*Úa™%û,î·Ûþ•fêìŽ/IÅÜÛó~ûœ({¤ªk=jš¢äêy}:Çî÷î£Òæžd6 ‘«àp䔸àh€‘PU%‘ñ%R ¿†°¨QAæ°É˜Á°àÓÈÀÒ¹ŸoÞòNýýÑs£çü¨ß ó4~Œ=Ù”>âúý8zîìÿмéÍ_r½o¨ËÎû¬k€7/iÉiŸÓU˲iðYípg³MFH*h¨b¨zôa[Ñäv^R¦±l©m¿ØPÝ‹ñ:ç:r¶7o -IèÅæÿJ€×X6»ÞÜHýyÝíI6,‚'OEádõÚY‚È­ffá´ý“Ó~Àšzn‘Œ›Å0TË“9¾)Yàp¦bfü€±ÝQ—v¢XöI?äi7b5H<;ƒäì$Ùw­ßÈ+CËž/ŸžAÞ|5PA÷©Î¦ÄpÌ4Ç:¿ß’.òI×}Ý"Ùë^–LïBVBÏ-|åJPö¬õ÷7ŠŸ—TµŒaS-ߘ.°£ög€4A~³ãì°ßµ'.ù<9,bP»èGlø‚»L›;ÒéPø‚¾Ž¢æd½=ïæbP¦¯$Òð˜ï¯cöáIP]Ú^4§nŠ¡!²;3¯¤5²At±¹MZ7%?’@îvO^)à>Sn™·7VU\íþ]_¤}ìÆb3sÕÁ¹¤E~Ä4Ô ïxÇÈLˆ/nÏsÚMNJ8h2ÖµÁY)Xõåʬ$ß2­I×a}íÜWº^_”àçß-;¨QÌL帙â7k#¬{¸BVéyVŒ¿JÍã€dÜi‚YȆ–Üæ[ß6“$«ç|¾6B›¯Jægþ»©WÜ‚1ÿO˜³‰¹/wõÅêgMh·|p{Òõ9íF |9zIÕížÃ!d¹ùóú]éÎI?àÕýï=uLKBSe,Ä¢‰‰}®YI¸IZd *_›.Qàhé£êpZ èðF&T¬ª¢ÜÀO‚k‹À2k‰¡'¡w¶êK.hñkïkyßAÉ>ó7†O.Ä Ÿ³ÛÊåZÙ”žÕÜöëýÄðä…EIìéÒ· ÕÿØ9ÍÙ±ãK¶Õr‰’-µ41 çΤ]õ!Ç@î¤û$¸(O,:™ÃlŠÁyE`A&v/™—Sëèy«%[>g„Ò–„×%³äx.jÁ_¼Æª?ÕÁ©ß-q5ªÝ÷JhyZ qÔ´g¾³qô¶´dF2îÎf8(YÉy‹S¦ 2]£ÆOúl^©*�¾äz|ÆuxR•¯ÄÃa"y"Ay¥µ~#¯K~T¬˜Æ}ä‡]Í Õ\>›~¡Rn˜�Û.KÆÝéb”h‹.ê"³µš ®½ßæÑê0‚v°ñš–\Ô’EÉþÎ7¥ÍßÊçûêµ¾'Z’&Fäx¢tŒÔq»isG2$µ K’ÑŒú— Ìš”ƒ’qH´08Ñ£õ©GãÄÛ.PwÑ›Œ‰S¼Ð”$&i¡ðÕïs?ÙÐ× ç„÷(|^ƒŒX¥f3Þëó&ð3¨•«�xµ ãÌò€ÌL‡ð÷BŽnì¨ÝùÉÁÓS¿7u÷šGWFê™EIÄŒ½ ußä)¬–1 \ !fÈ__äñºA¯Ëœýõü$“&ºPÂ;$Ü›.B:Š/&бÑYwìµx:Ñ tZfxFL0ME¸ 9'š->i·ømÉüò”i=ü¦ìÈÔÓ¥ˆ/‚˜˜VrZ“àWÙâìmΆÅëY÷%'ýÏÛ._t½±£°sv²8J®®ù§[ZæMôã ÂÏTÜ�Óš\“MR;$e.‰ýöØ«AmÌ-I½¥Y“PRõ—)È”{`¥Ê!Û(dQ‹ÓªrŠgüˆu-ý‚dŸ®5À÷“ºR�̶ØRv¶Ô~ù?”ëÃiIΖø×êß8P?ì©<ÛIEúË’½âÞdæ–Dqœ!4½%†öVÉ&"£@÷ž})V~GÈt`ÜÆ¢¤¿ØõîçJ<K¦É 3…|Ñõ¹­Ñ~ík/<«ÃÕmµ‰›´Mê'z 2³"Í™¿Ñ¼å~õ}C-hK#¸èZ¢y|•²†Nö@´ñjÈþq=>a·xÈu+„ƒ�³’ïq3¿Í׫¹ÚrÍ˃^ÂÌWPI™—„ön½Þ+’SZ±Â‰2mh_Ú½×ënçû%ØWîׇä°¯ºàsžÓ-äuª:Š×?Þ§}?KLûx&Á•%x™™ŠÏ£?Ââ'Âϡϋb™&áHÒä&ßäué,ºþëø?Íñ—‘6>n·ü»³åu#I솿ž"%•Ý£Tû÷ꜳzýÛjɽoZt^a‰‰{ÅøY«*¥/Ũb<ûºJ\í>¶Å°lRŽHƒæ¬Úb„v.jqá—ó³¿ýóÍ[þaŽ2À3W \Ênu¯zs5A˜RÃŒæ$áždŠžu÷50§r\gÏyuÃìϯ:øùÅo•¤ÕD^çð,›6wKÌXt�ÑÔÕÕ¼ÞldmEçö‘zæ¢0k[’@rPeI2ÚI¼&ôÕñ3cÜaÚïÁL½GL õ£ãËF9pf[­3°&=Õ3Ö´ä ?à3¶Ã'ì6ë°º¤‡5Ø%U‚·•ÕIq%šðÛ¸L½òL[ͦ"¿ÕSG.ÁÚh6²'ëÝû¤µõ1l-Z\èðEj·×·‰Çï“ñ“ŽJmbC-Oû!g}Î’d÷HÈ+çìÊÁ®Ï«ÂÜ‹¾sFó3‰ŠMàŒ Ÿ2pÀˆÇ£-úêÓjiÞ2Öõ–ÐëÓ=÷ÈÇžÂ�OG‡ Ê;/¹à×ê|B?<õÊþ i}hAÒŸ DHƒW›Fª\ò9ß-ïËU7OÚÝÆnÔwGA’¥žlõHcú['îù¥é×ü]PÚÒŒk`®Ç¦í"ˆM!Øå䕸z-ÉÛð%OFBÌgl‡IJø! žrÅõ®õë}Ýï¶ü×'³§Œò“Vù? <s™œ¦±«ÿ5iAL%&âe2!¶hmרs—«6»k°+žm :§Ïꈧü€i’›rü!&bTÝyI‡Únó¦¬yxA2šbz¾Ixl.'׉!—Š'‹{ÎfýVȸٴXWË X”ôÎ\ýSüîKíá‡À—@_CœïÏFÄóáJ&Ö ®YÒ•‡¡ ³’³À<¼!P>ç‡zo2Á¹."eýž·I8, Ž›oJçyÌõïv¢m§ŒJt㌎¶g%ùÃmÜwœ×0õ:¦†\ÕáÛ á°iò2"WÏãnÀÿ›ÀÉèÄk±¿'é5‚öWùú§S÷$^ÌM‚ü;ƒÌµ$‰zw\ûh¥êX¶¬’²ªì}šÇLƒ¬‡Àã%Ü”¶‡‡I9`2’ÉI&F þ!Î=•ªãƒ³ÚeœEÛÁq^su>á¶ù3»Í£Zõ\ˆ&“;ñ�êáÁ=¾r Þ †ËÍÒt™ÈÅyIÓžú×÷pŒTñ¢ã §"ÃÔÁ„*çIã Œ‹P¼¨Cµ¤PË(ºCX*ìɸÒôŸÖmTPØÔ’§ýϺŸu]Néx‰rÎOÎåòžÀõ2žªç«%ZZt˜£;Ýtè–ƒNtÎîßdZé6ŽÜ7ÞhcæÞäÀ¨ é µü…ïó°ërN ^pèÓ6p—ð¼º_é&x1_%cJ’aÃȹÓ>wÇBìí:à¤ò€ëp›i¿âk’™Û^ÌœiK²Õ@òÒ(SIí!ÓvoHèO·ï\þ¾æñÿiAÒ›ƒ†’ •ë“ûáx6ÖD/ÉQ$¹D¡ê�ëÇ9ÉOÚþÌmñEõU?j‚ÚLå\^­õÍk¬õë ~;—¦S87cÒ-¿i ž2Ú7e)l¼`—îç®uNÁaÕ2Ô’–˜dVlS{/½ÂÜŽÙÄü³æ žôC°;<躜Ñ£òŸ:8u“‘H5àß–-µÞ–­ü¤H¶”ˆ0f¬¨¥ðe%"7þ|‹î2x6yT2™“„º—9øì¿êj‡øã¾ç,;š–ô6Ô¿¾B>«Øîñ½”=”à†äþ!×唿(úDžwUí˜X•?ؼ%¹+™{£1Éw"I Án‚¢íóŒmMÀ_E( Ž5Ê-X–Ô)<í`-•dË@ïæ¤ùî-ïH%Ž}\ce9”Ž8žðžÕ«ZÎð”èŽNÖnÁ‰ô¿X°§4½Ïá'UëÈèû!¼¼J9.gÃBhc˜“t—Õ‰Ó oVõ�%ª OÇ™¿Ðįg‚6*]”ب´îj«Xî¨eC-—´à9?⋮ǃ¶Ã©ÉapÚÀŸÆª¯"#Ô݃÷Ьî:øÿEqÆ¿7]Ù¸/™ùÍ—™©WnxûöUJ.iÂÁ8¸l€ê”þè~®JÕMGö+¢yk .Ó$ÌFWƒ,V’²'íC“DÃSªVNê<àvxÀíð¸‚Ë»º·8ôIjËUî¯ �ÄŸ«<¹�l<X§£Sýx¶È¡’TÊç±Çp¥5«@G—|Á†‰T†¬éKsÔ]œÓ~Cûß#Kr‹i}i„ÍI7dF.úœ3š3/ 3;ÈÛ²…¯ì·?\®ýÖ�ÿá4™yn1™ë/‰iÀÜuÄLÿ3îQ¢®FïC_b€IH%‰áÁD…¦lªå?ä3. OéX»úÏ <íïo*ÓЫ­õë†>ÿUqÆ¿-™ßxm2ûû¯KfÊú_Ùð%*Pe…l¼žwYûŠD+(Á2î…N„ñzê‰c†”›¤ÁAi0e’hÌ8ÐZàqè8y,Â5OÅŠø×áy úñ—(ïˆ=¥jJI=jwÔF¤ê왘è–ctI/»i~âÏ‚h°'Ž×¦³é;$•S\XØR»nÑF¼÷þón§8„y`I’ŸQ ŒaÙ…h±§Ê­nWç4ç¤rVsúxÒ�m«îëÏ€ô4ͽéâ¼HòßÔªQ#lÌ~¬’§%¡I`WµEiF¢Rr4k0-É›ÿÌno\Ôbs„îœÒüñ‡lï÷_‘L½—¨üD´˜ò:IêÃ)BCð[Íe¥ÈœìvÛIÙm û_ßÌÖ-¾KÀ·å­N+J¿CÝ€ÓV[‹²e•Ÿ]S„)‚ÌOe#ÔÆŠ¡Ù~ÔJ_‰•Kåà=ƒ@¥jЇÖ^u긨/øœçãw:­9Ïû[“óóË>§°S3{íÊêÚpUÇóß·ke{ú¼¿p·™jl©}ó…U)ÙPËððà€¬ä±'“G§òB 3PÇvÜäÍ8/s\š11c¬ê›ø=¹Yo–ñý¶Ôr*üOÛ¾¨ýêGµhOƒ_aew4à†lPv Õ¿¯ BûìÖ »´%íšÿjv™âVR\}ulª¥7ù»5ýêæÿª¯ß(Îû6²úF3÷ÏoMš|Îçãçó†dŽw7—HÒ¹hp›óÎtþG¤?Š4ƒ,u]t¬Üîó1¬)±"‚¡ºq¢·£v¬´ñíF‚ËÖ?gàa*½<>¯N¬ö¶c�¼ÖZ¿î�ø ·cÏj¾ú‚}ø½Ùʨ§î×.hAÇ[Ö%cIRÚq¶1„PE„@^­3šs^ êhKðèì%Ó 2ïñ\ÈãÚwªcTÅFÙÄ!ž^4üýs×ã·Ã³1ðøPUL3!$ <tÞß<q?º�þvD´¾–ôb%æbÕUj¨~\-èU­‡² sÁHGó_ùÉìð+~¹8[A‘% *WÝ›Ìôc YH€50FQÖ¬:ë<ÒSÏYŸóˆ HIО×I0¯û@þfóæö¢i¾Ñˆy{(+NK¬†«¨¤ð¶¢0ú¼$4Ä«%ÅÐE- Ǥ FØÒøÁÆÁï¼ßîLojùÛ=µ§Îkþo’¹7YÕã”Ìhœ¤ctÂøò‘³ ·ÆñiðY×9‘«>?Ä×]+ 78îðU?QZ¤à¬ô}ÉŸó¤òŒrÆç\Ô’n$n¬<RÛUÙ5Ã5'IT@˜0‰4öè¶4¨X âÉÕüW´%a CCÌøê“xDl©å?â?äœÏÙÆ2Ø}îMÿjÞ­ |;ñ0è°{ òj¥µ~ÄnN›ü©Çdðsß”.~k_íûêØ’S~Ä´$$EŽí¨{:ˆ=Ì4…ß;ñsÀ¶ZÞšÎs´8æ,JJSÌi°Iöç4 Ýà”Ì_ðŒò˜ë×+Ýmy°ze犫¾ŠÅoAL*ž—ä×óSú¡r½¬A§9Áà±$GŠÈÓ*‘t X Ïí»t-!Aè©‹Ú¡kõq±—œ©ß,×GÝÔ>ôíæÀ_Ò≠Ë&å¸i’$S„1¯ÿM4F<êmè#IÅ€Õ±V°¾ÅV¤ ÷­ÀÓúÓ~È—]ŸG|/»>«“Y¾UÕ°®ëos´Ÿ%0Ò•îÅ3~TvÔ­^Ôâs?•}ߺ¿¾¦Êiò˜øÖÐ Rx›ZÒÑ€„äñÚ*£Þ®:ú8n“ýÄQ⹤E`ˆj ÷oÇ^—Gi“`†êéÄ?ïP} ê÷ç¤}PàÙµ'Jô1Ôͪ–ŸîhùæµQ¼aò9Š׌¨Kì5(É7£¼YaÞÏz´ Úñ–q'"²Y±nù»9º?Y¼ôêdúe˜‘ì¾%e^R¦¤’„žÀƒ…*«Zð˜ïói»Ã#¾7Nx€K~·/žÜíf:ùŸ§ï=ü›± º/q~Hßçcqj z¦Al>¥Ýiºê"Q"$dN•u,·šÖ7¯Ùòì¦ÚßëiÿüæÞøÀ0h¾ÐÀ× @ôcê ‘(u›´é˜PÈöÙ{Jô‰RËK¶æøq£<€¯4ø  'Ý]o‹K:úاìÎ\Ђ a;Vg}Î?Ök¬ä«ŒH€’¸8f"Ós,}SkJ÷ñliI_=•‘g3êä5â Í ‰„ÍS™Æjìy\ЂµÝükÏxNa=âà{ßV-^ùc¼óƒþE)ž}¾}ø}£ŸÝÔò.ú¢ùB¬î†„à¶M™YETÚ/c®Cn“ð)»ƒM5ؽŒñv½LÚ¬ºþʧ:H.hQúϸ?ŠCïeµ×bûõ–Þ“8¤9ÄÏ%è2ª3oKæoiÝ}áWÍÙÞï”—Ü“~Xið]æ†1-‰|kvx IÃPšÈ¾ú…Zõ‡5\O„Ì»‘ ñ¢Î¥½˜à”æöcv{ëŸ?ðýÙò¢¿×QÇi7bŽ-n6ƒ‰"‘¤!¬kÔÁ¬²€Hx ¬Æ@ëÄÀgkýì‡VÁ?âK®Çç]—/»>ÏëhÌêŒPçŸG‚K=ðm�ë1�v®s­ßн�ܪ–£‘óÞ¿ðèO5~OÏ»ÿÐU%ï#5k¾“ÝQDŒ\Ü}£ø–pVsiƒ³š³áB‚=P϶¤%T#ÁÍÁ�ݸïòèÓÅUZ±�Ÿ5ðHÔŒÝoO€–£5Ÿä?|ÿ³~Ä)?b5Š ãÞh°¨Êãû6#kµYõ9œÀE-8åFUKhèÐcãωpÈÿZž/þžûO·Jë kZ|GÍsJH€«$º‚U‡êyÎø´Ýáó®3ÞïŸðá\ÛåZïßýÒ˜÷½¨® ü€‹®ËiŸ3O ‹0ÊÐB°~DG磌ádž·lbÙð«jF ;Õ [˜›Oéh©ïýÖŽºÇä_~CºðþJ²*6cbO32‚3„C$&;³û’ÙæÀíÜ7P÷B×v×mÙôâU~ÉÝÝϥǤ‘®HöˆÂ/%È?vx6Ô²ªåX³Q€¹á‡‰hVVHŒJ#©T«–îÄ̳~�–±´˜ož©¸™ª¨üRï¡Õ®»ˆÿøz0§cP+b†W_äUà[¯5þû7ØPU ÜPÛëª;÷‹ù)]–ìï~G²ttMÝÏÓ�w¬kÉ7vµ¯ìN"œ±V¥ýKY÷èèÿoïÊb$»Êó÷Ÿ{oUWõ:«=‹Ç±ÇÁ˜-2‹‰±‰€âˆ,$‡y"lRPˆŠ"EÙ ˆ$YB ŠH%Q$!JBŽM<,ö`À 3ÆÓž±gÜÓ=Ý]Ý]ËÝÏùópΩ{êvuOo3t›ûK¥™nõ½u—sþõû¿?ÿPvßp§hî³cÒÌ{ÃÀó²E} t ‹'’Žt/à‰kð;(ÐSkà†Þí'ŒcÑ/ÕY|\°<)ŒŠšæøs÷y“õP¾<{QVªöÏuªvÜ»Ï?¸O#å†<À>-©}Ó= @+rpèŽô¥]#x‘“´«Ôüå4yúvùð¯>ö"'wÍå&ÈÃA p„j8&꘤À@æØÔ¶™s,Ϻk«RD¦ñ¹Í9žR!¾“­à‡ª‡ÅÂÙ ø—UÕ•#¾–Y÷!¶ØÈžhCöBV3ŸŠ_¤›EíÁwùûïh«ôÁ•bÑöÄ€&BhG·Öo‹`äÀU¸ @3,ÅàìŒìÔÞC/$PŸh™^½«*Å2ô@å&&Ø™–‹žÉ‘äóég<=¾,*éwOÜ:Ù~´û[µ›.¥ÚG/©äoÏÊ3œ¢Í9b¨>�Dšµj'Æ7Hô÷·ÕI-α¢iþ¾(@ÏIàÕ¤ê’çUÔùb67û6oòÏîÞç§Z¦g¶Fš–Ѳ©x ôXj@[Þv£Ùÿ àªãàÇæÞþ,4 Ô«¡üHvðp¾‚ó*DL:ȰÁÅ(tz²F„” *Å,§š³×|ZXR):†¯×3Ç74eݽ¤Ò ‚lÎˬ['ñÐ}þÄý p 9þ[!ôØÖàíf8DŽxu\–)fÂ=0Bâ‘.«— Q¬å‘M´Ž3¶mãG�¼—8=–1òj’w‘€W(à¸Ë 6!™¥¤2WF†%ð(@c¤¡¸M ówÂÓJ­«L$&L™ôßÓ,£æØãN¾¯]–À<ƒ»Æà¹�É|HÄ×2Ÿ­ÀhûàÜiq>×e‰¿SsmŸðG’ù¸-+pJÚogàõµ%�KKr –)8OÀ*fõx[uö{ [3VGSðþlçó‘¹!ƒÔäÔLçî  ^ÒSú€–´¤]¤ß*%È~Cä ›G„÷)‚w $û£u:z ÏG¦eœ1øó#­ØÎ”*èÓ�ÿ~ãÎÚ~Qó`¹P™"{ÖËLñ~Ñ{c�;&ÀuÏïPj'EÈ8‹z,–(|1Ë>ýàÈ œžº¨lT¯ ‰�Sä£iÒc¾ñz¥1p+œ£eÒlèèÅ¢˜#VXD†§eçTè:{§=à,k”mì¼ïŽy× Nº³w ßÀžÈÁòÙ®’ßÿB:Ûª“øf~E¾)*°/ua³C ¥ :8û¾ó\ÞÍ œ%@öOù<ÆH|¦qkÆ|2—@ÄÀbî¦È@Luè1Ð%Pj?bUô9Û+�ÂdöoÙB÷Õ¿Q#:Õ…|k õ& œ``Ì콎�­�h P§ ™÷XùB×Õ›�&hdà(�MçàîcªóaÖºfÁA zLvâËçï#ñoßKœýù<2,+Ýž±d¾¾é1žQ).¥o àbéÝ[ÀCÉø²ŠùŽlèÑ|?R!Úœ³ö ðp„„<kŒì¼¡+Œ ‰º4þl¬ò\ \ê±zažóf$x"ƒ”gdgùŸ³ù¿_pÓý0µjŸ€ãêÌ?„©Õ "ŒB_Cȇ)À<gG ø±y®#‚%ÜÌP#¸]´'˺&“(ÆœJ0-Á5„d”çÒÁä^Ol "ÃÐ\Ä”2¾piU?º´ÇŠ¢¹ 8ÖÎ~+ï‚4ºNÑÙAyfXk–еÁ�‘‚…DΊÑÀŒ�ý€€&AMµzÆ–›ÖË2p”C&«ç<à»apƒ5š²fP\†ü›œs0+› …)ÞmäÜ÷’ù´×6øн:¥]îC½/©çdˆó2z°Ãê4k©õ2Có]êwbJÔöøhÁ^Ñf=0‡®Ç s†gV¥ˆ5ÒsNÊ0uÒRù.ŠüÖAF¬Z‘”Ï|F]JnAü1öþE3ÝÞ# .‹èÀ3_–21iÀ%α=à9wÚRmŸáÔe1ù2—d±†­ò[qÚwʆïz<Ã5÷Ä r&¦.— ˜b aæê Öë¶p¼úTáý¨?cmàâ*ÎX] ç p­É@MˆOêoôYò5qã{BÍr*Zz¶ÜyÔ#à{�¦Pg°`@)}NÅ=š �ŸLŠŽõ=J©ï#s‚wÞ¦�Ϩ0¾Âéåiÿ#¬¨ø³s*=yQU�ÐD KEÄ÷¨�žt€MårÎíbå¡ççÇïíN«èëT|ïweû¾EÎ÷§à`Üð«rðñáôÍ��IDATÜ Y¤é´FEAÿ @W`Î�ÒÚ¬iûR'J¿«kC/qžž‘³¯Í¿y‡?õ»]–†ÍÉò³)Ióãð0c†:pÞícPOµ‘/y N "¾:õönʦVad‡A.P�`‡<º,׋¦j¯­?rB®S„äuæMï0lîx«qS§Ï©íÀ½ãRí‹7y)ðaP�2 $ÜF“•Q•îÏ*ùnŽsÙæcTŒù°ìÞeGÃrÝÛÊQNy<0Ë ÞÉ,õ6`¥‰TŠ¥'b˜4Л(Ø‚†lVZÞã5x¯ÑÉÂ>Ë~ã®-Þ‡,1£<¥zø¾ìâ’-»€¯ð —^6~»ô⬃@¯ µ˜q"Ú*ÿÊ•ž @o ·µÃ±I_Ʀ‘;0Cˆ-b¹Z2ÍÊýzˆBF‰g¾ðqxš–,Ö°›ê\*¥:‡±d\ÏgQÚœ9ûoÝ=ÁCö„ÍÎH@JgO�h¸{bˆ®Ùìžèwj¥à–пo±3 ‰W’!©u­OÅýù\.o¯^ËýO‹ó¨Çrî“é Þ¼O(àç"–·ÅàVð•>èRIKinkøl}wÉünòPçÛ4¯ ’àJð~&ðc:MšboT€x À>h ®,˜Ö°Hg­X²v°û×=„9ˆPægeÔ~R„_=@Á¯ßå P‡BƒÅ€´e¡1òqLÔqBÕÑoñ'ÞõålñÙ6dÔ¤€ïö&ÚPrœM¼5 ÚÿçŽ>²ë¦¯'üm>å@ÚanpGf-Ý å¤œEa°i2ßDÄ·‘Í®J)VªoÄø%Nea9Ç—6ú:÷j¯Çmp È,YËà«©¬|‚z%@`¥úPýž‰`"Ó±ºÀ´¹&Xã˜Én÷Æ&‰ècÜŸ<^[/=1‘ÌTˆÓù ž,PkXo^·N;ìšw]úÓ<_JÀH8ÏÚÝ�t)�}{QfGèÀ·æÀ!¦<à `ôë¶™©eH à<WíDå`H  £tj?vzìÔ¯Üh¦ãD|[¢‡ÚÍ{;¿'¬Îc­ Ä_ç{Èi-°ãËCs]G<²“Z¹r˜p>߆ ´ xV‚'̽NéC•ûãìÌ—€M @­£G8¹§�’v^W,?‡nHÒ…z™dãxuÖ*⤆æ½EKÈ{gdçùWzOÞÁÏ/T÷8y&ë! ‹Fõ7IàfªáÕÞ(9ÃA ð/ÍÃû×¼õØQ¯ÙyoíH=’ ÀÙ^eù¥×‹±ÎZwg?Àa›‹9w Úæ¦ö‚á+ðÜQ™óûí(ƒòfw7m«û߆mtÆjš5{}¾9Gûäz‹1qjY ˜²ê¾;œzãcý¯0|œ‰0$º7ë.�I§tbsÁ=þþÚaQOâØ"û½k’‹:ßE•àŒìàŒìôQkø–êdŽÂÚ .Ê’þ4Ÿä8ÍÀ¡ÐJìª�=/ ¥] º4¨  &@i²õD§ÊTÎf¦;¦Èë%2JÚF1¶Þc•k w Þõ~{yOÀyöâk|œû°mî irŒŸÛd DyOÆ&ò´ÇææoÝ̫۬±YvÀM+ιm�ä~¿MM'N©¤¯䯖ˆëX¸†/sÞ[ z‘õ”ì}³Îô…[ÄÈ Ö¯�‡©¦‘ºfÊ‹ö𳢚\9ï nº‡D€Y£Î)fT|ÿ´Š^;EÞgG :z¦¼~vÎ}nÙø¹}ä¹³(Ä2|eè~x‡”»ÙË‹«ÜWw-ãì~¬7cëÁ5ÎãžK–Î5l,¯}+<øS£ ˆúäÓ |Ô€–Œ F ¼_®=°_Ô§Êb50rGB°¹Â ~ ºxLv0Óߣøo�WyµâK°Mʤð•“öéG®Ù–à1“²kÐ0imŸt«˜({×<¼jà¦ÏB'}×qÒùÑ”>nà³Û«{¢\7²†êZ=±4Ä�zXÝä f¯‘Üš©p”ß°HÒ:=¶g9qÎ)K'Í5*gn…êÐ]çöã>ß@6Ë©ú–lÏŽÁûü<²ãSð�ÚÈãfQÃ( xDÈX`Q€¦ðtŸ!yð)€ÂŒNûŽìàiÙ;Õfù0é ”2k_9†Xù;°ˆË±ÇŒßZýºlvwq‹!`­ ên —Å,s6 ØÀµ¸çRX‹t­ƒY)&‘*�€T¨¬2ð%¨!�_ÂyoöŒ¾Å?x ~u êSº—-gîOÚ8'C<–·ñ´ê3ÑœÀóªðÝ4uRª÷íf(K©»Ì©35MÔ×0tpu�op`HJ0t ^èDzÙ6Sú?Í{‚J»}G$ë¼Ãò%ƒ ç™õJQ.†¤”C§¶›8÷X6¨¹q”ć`³kE9ל—ÖœtŸõ3*”uˆó¯äÆì'ÿÂm¢ñÛs*G&"´d†&y ¦_ÆÉÃAÆ!0>€ ßÌ—ñÕ|ÊŠf9‘÷™ïs#±Ýšß0E³+馶q?;þr_üF7ÎzL&›Ý€|×±ü5nM¾CIæ¾Ç¥ff=gÌô-qŸx4gönÍæFn¿ý¤?ö…ÓªÌìÅ\O¨‡†ó¿Àš†í²×ohÀc<ˆZŒJ5™Ý„ôÜH ÔUr6Ší¢à\´µ™”rJ0q¢¼r o78 {qOlGßÑ„\‹5€®ñå*'Û°^K­a*'K¥ˆx«µôòZ_ë½ñª.s~ᄨîµÞèéó?Ψ9AB†ïØd™ÆÉÃaªá% œá´lãt¾‚g áû8¼/Jp*Á“Nm´º«vW—“ì„£À;øì7}\O¥™ž¤Þ;šã72l6O+ ‰1òî ™—&EÞU;v÷»kG/ ;~ÊÖ³Ccø.ªOÈ.—\,@_‡FÓ¹p}›Î+÷#î¥5 ±mè—Rc^ÖJ ºKÕuÌnü´í‰­^'mòXÞ@ļ^”«J©ÝaFL9ŽQZ2Êj›NåFl?Ïq8+Ó—8ç׎ýÚ%οr‰5Š|Å䬉 n¢�S¤yOÏ«gUèrÿ~:†Š%Ø3­„AþOìDäWÉOÖY¸¡ ì»r9=:N>êDè*Í_X!ã0x7Šwúûð6òÞ£þä½,�ù(М•ÊÒu%€iÚžWzÒÆ²‹‡óe|¯@w^À´“î´i A¿^Œ$72 D) z­ÔØf¼ía «=±§ï±=m4’öþ×+]a‡× _#*f�yM«èêŸ&/Šƒ¼ÿþØ‘Œùƒ!˓˜!eFHšSjÞ?¼h&W@ƒÇþ]�*×m#(Òà«î¥2~•lX¾‘·ä;½©³ þëHñƒ9F—õÔ‰&yðÜ!Fð*o'¼1(*9[Jó™·ò‚Jð¬ ñ}ÙÅÙÁSª×‡¸þÑžuQŽïŠù};õìDí|ÍÔRµ‚_–Îóv£UÞäÏ×ó~ú¤W8¿ÂÉ÷~œ†·Ð_2øxÞ'þg“u·¦ÌÇ$8ò4ÓË4k6¯ ²ÓƒÊH~®Œ_%–Ï¥3|¸´NÒÈg°rY%¸ 2C:M'wzMÜ ‚ÐN}‚fMÌÌ2ÂecZExV…xF†xRvqv]| ÀìSK(àúe°Ë^Wf[IíÕ(¨’Ýõ~y—Ü‹ÆP=�^ é ÝnÑ!`Mj(ˆXƒnîgh®fËdå¶YXÒ;–®ßÓJÕú©dB�Ä[½É‘ xG%øçoõ_XPÙ‡º �‡D ¯óFñzo· A@—õ˜¦),Ê —8ÑÆO†˜V±ËE�Ïà €–*�-]è>¥9�³Ðî+¥È¯Rô•Tò2Ñ1( &�ìp�Àt/lº ¨?ƈu€-#ØlÑŠa+ÐzEVƯ’Í.LàÁk àÀ8y?ó›þ¡¹+œ¾±ù6ô¾)ò1ÜŸWè‘žÏØ3Ã…gTŠÙ¢‡�®pš€+†³1u<·ehvŠ«æ_K¾½›ûû*©¤’­é@6—±gºwxcr§s #wP•ñ«d+‹Óƒ†ãù ÜìGè¦ÖŽ~9fõÚËÌrúÀNµñ3Ó§;,±€ÌEfÀÓÐ)NkôÊ ×N XÀ óO²W­’J*¹¾N¶�ëÐ=°–þn³,@èê¸2~•luazf!Ž›´Ä!¡y)÷ù ©:hÒíc ©ôXªWàÉœçàUŒ™J¢–¶Ìå£l¡`×·¹û½†ð¬¤’J¶f�mè;ÿn”ȇ5ÐòS^*Ù¬¸yu›–æ @ªÇ/q—´Ñ Ln^FÁ�*ãÚ†Ýa|”––i݉•TRÉËRϸ�Ïìÿ­°�­¢­¬Œ_%[—>Éý9†jfwYÆÏdhÈy\BßòQV†¯’J^þp§Y€ª>¿JvdQºdÍe„Õ(Š}ƒ#\Üóì>ÊJ*©ä'®õóVα!ëYI%ë‰]?6ÿng‚ÕKŸµx*÷e%•Tò2S^•T²Ý5ä§=lœ§r¯ñQVRI%•ñ«¤’¡FÐß²žÊ½ÊGYI%•TƯ’JVÁaÿ“в’J*¹¡òÿ‡ÙI,Uk°”����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/Makefile����������������������������������������������������������������0000664�0001750�0001750�00000036544�12605311455�014424� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # www/shoppingcart/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/yaws pkgincludedir = $(includedir)/yaws pkglibdir = $(libdir)/yaws pkglibexecdir = $(libexecdir)/yaws 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 = x86_64-unknown-linux-gnu host_triplet = x86_64-unknown-linux-gnu target_triplet = x86_64-unknown-linux-gnu subdir = www/shoppingcart DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} /home/klacke/yaws/ac-aux/missing aclocal-1.14 AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 0 APPDEPS = AR = ar AUTOCONF = ${SHELL} /home/klacke/yaws/ac-aux/missing autoconf AUTOHEADER = ${SHELL} /home/klacke/yaws/ac-aux/missing autoheader AUTOMAKE = ${SHELL} /home/klacke/yaws/ac-aux/missing automake-1.14 AWK = gawk CADAVER = CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -Werror -Wall -O3 CONFIG_STATUS_DEPENDENCIES = $(top_srcdir)/vsn.mk $(top_srcdir)/applications/yapp/vsn.mk CPP = gcc -E CPPFLAGS = CURL = curl CYGPATH_W = echo DEFAULT_CHARSET = undefined DEFS = -DPACKAGE_NAME=\"yaws\" -DPACKAGE_TARNAME=\"yaws\" -DPACKAGE_VERSION=\"2.0.2\" -DPACKAGE_STRING=\"yaws\ 2.0.2\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DCPU_VENDOR_OS=\"x86_64-unknown-linux-gnu\" -DPACKAGE=\"yaws\" -DVERSION=\"2.0.2\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_SECURITY_PAM_APPL_H=1 -DHAVE_LIBPAM=1 DEPDIR = .deps DIALYZER = /usr/local/bin/dialyzer DLLTOOL = false DSYMUTIL = DUMPBIN = DVILATEX = latex DVIPS = dvips ECHO_C = ECHO_N = -n ECHO_T = EGREP = /bin/grep -E EPAM_CFLAGS = -I/usr/include/security EPSTOPDF = epstopdf ERL = /usr/local/bin/erl ERLANG_ERTS_DIR = /usr/local/lib/erlang/erts-6.2 ERLANG_ERTS_VER = 6.2 ERLANG_INSTALL_LIB_DIR = ${prefix}/lib ERLANG_INSTALL_LIB_DIR_yapp = ${ERLANG_INSTALL_LIB_DIR}/yapp-${YAPP_VSN} ERLANG_INSTALL_LIB_DIR_yaws = ${ERLANG_INSTALL_LIB_DIR}/yaws-${YAWS_VSN} ERLANG_LIB_DIR = /usr/local/lib/erlang/lib ERLANG_LIB_DIR_compiler = /usr/local/lib/erlang/lib/compiler-5.0.2 ERLANG_LIB_DIR_crypto = /usr/local/lib/erlang/lib/crypto-3.4.1 ERLANG_LIB_DIR_erlsom = not found ERLANG_LIB_DIR_erts = /usr/local/lib/erlang/lib/erts-6.2 ERLANG_LIB_DIR_eunit = /usr/local/lib/erlang/lib/eunit-2.2.8 ERLANG_LIB_DIR_inets = /usr/local/lib/erlang/lib/inets-5.10.3 ERLANG_LIB_DIR_kernel = /usr/local/lib/erlang/lib/kernel-3.0.3 ERLANG_LIB_DIR_mnesia = /usr/local/lib/erlang/lib/mnesia-4.12.3 ERLANG_LIB_DIR_public_key = /usr/local/lib/erlang/lib/public_key-0.22.1 ERLANG_LIB_DIR_sasl = /usr/local/lib/erlang/lib/sasl-2.4.1 ERLANG_LIB_DIR_ssl = /usr/local/lib/erlang/lib/ssl-5.3.6 ERLANG_LIB_DIR_stdlib = /usr/local/lib/erlang/lib/stdlib-2.2 ERLANG_LIB_DIR_xmerl = /usr/local/lib/erlang/lib/xmerl-1.3.7 ERLANG_LIB_DIR_xmlrpc = not found ERLANG_LIB_VER_compiler = 5.0.2 ERLANG_LIB_VER_crypto = 3.4.1 ERLANG_LIB_VER_erlsom = not found ERLANG_LIB_VER_erts = 6.2 ERLANG_LIB_VER_eunit = 2.2.8 ERLANG_LIB_VER_inets = 5.10.3 ERLANG_LIB_VER_kernel = 3.0.3 ERLANG_LIB_VER_mnesia = 4.12.3 ERLANG_LIB_VER_public_key = 0.22.1 ERLANG_LIB_VER_sasl = 2.4.1 ERLANG_LIB_VER_ssl = 5.3.6 ERLANG_LIB_VER_stdlib = 2.2 ERLANG_LIB_VER_xmerl = 1.3.7 ERLANG_LIB_VER_xmlrpc = not found ERLANG_RELEASE = 17 ERLANG_ROOT_DIR = /usr/local/lib/erlang ERLC = /usr/local/bin/erlc ERLCFLAGS = ERL_LIBS = ESCRIPT = /usr/local/bin/escript EXEEXT = EXTRAINCLUDE = FGREP = /bin/grep -F GREP = /bin/grep HAVE_BAD_UNICODE = false HAVE_BAD_WILDCARD = false HAVE_CRYPTO_HASH = true HAVE_ERLANG_NOW = true HAVE_ERLANG_SENDFILE = true HAVE_INET_PARSE_STRICT_ADDRESS = true HAVE_SENDFILE = true HAVE_SSL_CLIENT_RENEGOTIATION = false HAVE_SSL_HONOR_CIPHER_ORDER = true HAVE_SSL_LOG_ALERT = true INSTALL = /usr/bin/install -c INSTALL_BUILDER = /home/klacke/installbuilder-5.4.14 INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LIBOBJS = LIBS = -lpam LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = MAKEINFO = ${SHELL} /home/klacke/yaws/ac-aux/missing makeinfo MAN = man MANIFEST_TOOL = : MKDIR_P = /bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = OBJDUMP = objdump OBJEXT = o OTOOL = OTOOL64 = PACKAGE = yaws PACKAGE_BUGREPORT = PACKAGE_NAME = yaws PACKAGE_STRING = yaws 2.0.2 PACKAGE_TARNAME = yaws PACKAGE_URL = PACKAGE_VERSION = 2.0.2 PATH_SEPARATOR = : PDFLATEX = pdflatex PS2PDF = ps2pdf RANLIB = ranlib SED = /bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip TODOS = todos UNIX2DOS = VERSION = 2.0.2 WERL = YAPP_VSN = 0.4.2 YAWS_VSN = 2.0.2 abs_builddir = /home/klacke/yaws/www/shoppingcart abs_srcdir = /home/klacke/yaws/www/shoppingcart abs_top_builddir = /home/klacke/yaws abs_top_srcdir = /home/klacke/yaws ac_ct_AR = ar ac_ct_CC = gcc ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = $${TAR-tar} chof - "$$tardir" am__untar = $${TAR-tar} xf - appsdir = $(localstatedir)/yaws bindir = ${exec_prefix}/bin build = x86_64-unknown-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = unknown builddir = . confdir = $(sysconfdir)/yaws datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} host = x86_64-unknown-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = unknown htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /home/klacke/yaws/ac-aux/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var logdir = $(localstatedir)/log/yaws mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} prefix = /home/klacke/yaws/_inst program_transform_name = s,x,x, psdir = ${docdir} sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . sysconfdir = ${prefix}/etc target = x86_64-unknown-linux-gnu target_alias = target_cpu = x86_64 target_os = linux-gnu target_vendor = unknown top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. wwwdir = $(localstatedir)/yaws/www yappdir = $(libdir)/yapp yawsdir = $(libdir)/yaws MODULES = shopcart.erl EXTRA_DIST = $(MODULES) EBIN_DIR = ../../examples/ebin EBIN_FILES = $(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign www/shoppingcart/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign www/shoppingcart/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include ../../include.mk include ../../erlang_deps.mk all-local: $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: ������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/shopcart_form.yaws������������������������������������������������������0000664�0001750�0001750�00000000213�12605311413�016511� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case shopcart:top(A) of ok -> shopcart:formupdate(A); X -> X end. </erl> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/index.yaws��������������������������������������������������������������0000664�0001750�0001750�00000000206�12605311413�014754� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case shopcart:top(A) of ok -> shopcart:index(A); X -> X end. </erl> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/buy.yaws����������������������������������������������������������������0000664�0001750�0001750�00000000204�12605311413�014442� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case shopcart:top(A) of ok -> shopcart:buy(A); X -> X end. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/shopcart.erl������������������������������������������������������������0000664�0001750�0001750�00000025555�12605311413�015305� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ %% a small shoppingcart example which tries to show %% a variety of tricks and tacticts to display a %% shoppingcart style page with server side state. -module(shopcart). -author('klacke@hyber.org'). -compile(export_all). -include("../../include/yaws_api.hrl"). -include_lib("kernel/include/inet.hrl"). %% this is the opaque structure we pass to the %% yaws cookie session server -record(sess, { user, passwd, addr, items = []}). %% this function extracts the session from the cookie check_cookie(A) -> H = A#arg.headers, case yaws_api:find_cookie_val("ssid", H#headers.cookie) of Val when Val /= [] -> case yaws_api:cookieval_to_opaque(Val) of {ok, Sess} -> {ok, Sess, Val}; {error, {has_session, Sess}} -> {ok, Sess}; Else -> Else end; [] -> {error, nocookie} end. %% this function is calle first in all out yaws files, %% it will autologin users that are not logged in top(A) -> case check_cookie(A) of {ok, _Session, _Cookie} -> ok; {error, _Reason} -> login(A) end. %% generate a css head the title of the page set dynamically css_head(PageTitle) -> Z = [<<"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"> <html> <head> <meta name=\"keywords\" content=\"Nortel Extranet VPN\"> <title>">>, PageTitle, <<"</title> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"> <link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"> </head> <body bgcolor=\"linen\"> ">> ], {html, Z}. %% the little status field in the upper left corner head_status(User) -> {ehtml, {table, [], {tr, [], [{td, [{width, "30%"}], {table, [ {border, "1"}, {bgcolor, beige},{bordercolor, black}], [{tr, [], {td, [], pb("User: ~s", [User])}} ]} }, {td, [{align, right}], {img, [{src, "junk.png"} ]}} ] } } }. %% bold paragraph according to style.css pb(Fmt, Args) -> {p, [{class, pb}], io_lib:format(Fmt, Args)}. %% toprow of buttons to push toprow() -> {ehtml, {table, [{cellspacing, "4"}, {bgcolor, tan}, {width, "100%"} ], [ {tr, [], [{td, [], {a, [{href, "buy.yaws"}] , {p, [{class, toprow}], "Buy"}}}, {td, [], {a, [{href, "logout.yaws"}], {p, [{class, toprow}], "Logout"}}}, {td, [], {a, [{href, "source.html"}], {p, [{class, toprow}], "The Source"}}}, {td, [{width, "70%"}], ""} ]} ] } }. %% kinda hackish since we us ehtml bot() -> {html, "</body> \n </html> \n"}. %% This function displays the login page login(A) -> CSS = css_head("Shopcart"), Head = head_status("Not lgged in"), Top = toprow(), Login = {ehtml, [{h2, [], "Shopcart login"}, {form, [{method, get}, {action, "loginpost.yaws"}], [ {p, [], "Username"}, {input, [{name, user}, {type, text}, {value, "Joe Junk shopper"}, {size, "48"}]}, {p, [], "Password"}, {input, [{name, password}, {type, text}, {value, "xyz123"}, {size, "48"}]}, {input, [{type, submit}, {value, "Login"}]}, {input, [{name, url}, {type, hidden}, {value, xpath((A#arg.req)#http_request.path, A)}]} ] } ]}, [CSS, Head, Top, Login, bot(), break]. logout(A) -> {ok, _Sess, Cookie} = check_cookie(A), yaws_api:delete_cookie_session(Cookie), {ehtml, {h3, [], "Yo, "}}. %% This is the function that gets invoked when the %% user has attempted to login %% The trick used here is to pass the original URL in a hidden %% field into this function, if the login is successful, we redirect %% to the original URL. loginpost(A) -> case {yaws_api:queryvar(A, "user"), yaws_api:queryvar(A, "url"), yaws_api:queryvar(A, "password")} of {{ok, User}, {ok, Url}, {ok, Pwd}} -> %% here's the place to validate the user %% we allow all users, io:format("User ~p logged in ~n", [User]), Sess = #sess{user = User, passwd = Pwd}, Cookie = yaws_api:new_cookie_session(Sess), [yaws_api:redirect(Url), yaws_api:setcookie("ssid",Cookie)]; _ -> login(A) end. xpath({abs_path, P}, _A) -> P. %% this is the function that gets the form when the user %% hits "update Cart" formupdate(A) -> {ok, Sess, Cookie} = check_cookie(A), _J = junk(), Items = Sess#sess.items, L = yaws_api:parse_post(A), I2 = handle_l(L, Items), Sess2 = Sess#sess{items = I2}, yaws_api:replace_cookie_session(Cookie, Sess2), {redirect, "index.yaws"}. %% force browser to reload handle_l([], Items) -> Items; handle_l([{Str, Num} | Tail], Items) -> case catch list_to_integer(Num) of Int when is_integer(Int) -> handle_l(Tail, [{Str, Int} | lists:keydelete(Str,1, Items)]); _ -> handle_l(Tail, Items) end. ip(A) -> S = A#arg.clisock, case inet:peername(S) of {ok, {Ip, _Port}} -> case inet:gethostbyaddr(Ip) of {ok, HE} -> io_lib:format("~s/~s", [fmtip(Ip), HE#hostent.h_name]); _Err -> io_lib:format("~s", [fmtip(Ip)]) end; _ -> [] end. fmtip({A,B,C,D}) -> io_lib:format("~w.~w.~w.~w", [A,B,C,D]). %% generate the final "you have bought page ... " buy(A) -> {ok, Sess, _Cookie} = check_cookie(A), Css = css_head("Shopcart"), Head = head_status(Sess#sess.user), Top = toprow(), BROWS = b_rows(Sess#sess.items), Res = if length (BROWS) > 0 -> {ehtml, [{h4, [], "Congratulations, you have bought"}, {table, [],BROWS}, {hr}, {p , [{class, toprow}], io_lib:format( "Items are at this very moment being shipped to the" " residens of the computer with IP: ~s~n", [ip(A)])} ] }; true -> {ehtml, [{h4, [], "Congratulations, you have bought nothing"}]} end, [Css, Head, Top, Res, bot()]. b_rows(Items) -> J = junk(), Desc = {tr,[], [ {th, [], pb("Description",[])}, {th, [], pb("Quantity",[])}, {th, [], pb("Sum ",[])}]}, [Desc | b_rows(Items, J, 0, [])]. b_rows([{Desc, Num}|Tail], Junk, Ack, TRS) when Num > 0 -> {value, {_, Price}} = lists:keysearch(Desc, 1, Junk), A = Num * Price, TR = {tr, [], [{td, [], Desc}, {td, [], io_lib:format("~w", [Num])}, {td, [], io_lib:format("~w", [A])} ]}, b_rows(Tail, Junk, A+Ack, [TR|TRS]); b_rows([{_Desc, Num}|Tail], Junk, Ack, TRS) when Num == 0 -> b_rows(Tail, Junk, Ack, TRS); b_rows([], _, Ack, TRS) when Ack > 0 -> Tax = round(0.27 * Ack), Empty = {td, [], []}, TaxRow = {tr, [], [ {td, [], pb("Swedish VAT tax 27% ",[])}, Empty, {td, [], pb("~w", [Tax])} ]}, Total = {tr, [], [ {td, [], pb("Total ",[])}, Empty, {td, [], pb("~w", [Ack + Tax])} ]}, lists:reverse([Total, TaxRow | TRS]); b_rows(_, _,_,_) -> []. %% this is the main function which displays %% the shopcart ..... %% the entire shopcart is one big form which gets posted %% when the user updates the shopcart index(A) -> {ok, Sess, _Cookie} = check_cookie(A), io:format("Inside index: ~p~n", [Sess#sess.items]), Css = css_head("Shopcart"), Head = head_status(Sess#sess.user), Top = toprow(), Cart = {ehtml, {form, [{name, form}, {method,post}, {action, "shopcart_form.yaws"}], [ {table, [{bgcolor, linen}, {border, "2"}], rows(Sess#sess.items)}, {input, [{type, submit}, {value, "Update Cart"}]} ] } }, [Css, Head, Top, Cart, bot()]. %% this function gets a list of %% {JunkString, Num} and displays the current shopcart rows(Items) -> Junk = junk(), First = {tr, [], [{th, [], pb("Num Items", [])}, {th, [], pb("Item description", [])}, {th, [], pb("Price SEK ",[])} ]}, L = lists:map( fun({Desc, Price}) -> {tr, [], [{td, [], {input, [{type, text}, {width, "4"}, {value, jval(Desc, Items)}, {name, Desc}]}}, {td, [], {p, [], Desc}}, {td, [], pb("~w ", [Price])} ]} end, Junk), Total = total(Items, Junk, 0), Tax = round(0.27 * Total), T = [{tr, [], [{td, [], pb("Sum accumulated",[])}, {td, [{colspan, "2"}], pb("~w SEK", [Total])} ] }, {tr, [], [ {td, [], pb("Swedish VAT tax 27 % :-)",[])}, {td, [{colspan, "2"}], pb("~w SEK", [Tax])} ] }, {tr, [], [ {td, [], pb("Total",[])}, {td, [{colspan, "2"}], pb("~w SEK", [Total + Tax])} ] } ], _Rows = [First | L] ++ T. %% The Items are picked up by the %% formupdate function and set accordingly in the opaque state %% this function recalculates the sum total total([{Str, Num} | Tail], Junk, Ack) -> {value, {Str, Price}} = lists:keysearch(Str, 1, Junk), total(Tail, Junk, (Num * Price) + Ack); total([], _,Ack) -> Ack. %% We need to set the value in each input field jval(Str, Items) -> case lists:keysearch(Str, 1, Items) of {value, {_, Num}} when is_integer(Num) -> integer_to_list(Num); false -> "0" end. %% the store database :-) %% {Description, Price} tuples junk() -> [{"Toothbrush in rainbow colours", 18}, {"Twinset of extra soft towels", 66}, {"Hangover pill - guaranteed to work", 88}, {"Worlk-out kit that fits under your bed", 1900}, {"100 pack of headache pills", 7}, {"Free subscription to MS update packs", 999}, {"Toilet cleaner", 1111}, {"Body lotion 4 litres", 888}, {"Yello, a lifetime supply", 99}]. ���������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/source.html�������������������������������������������������������������0000664�0001750�0001750�00000006310�12605311413�015130� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta name="keywords" content="Yaws"> <title>Yaws</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <h2> The source for the shopping cart </h2> <p class=pp>The shoppingcart contains a number of tricks and "preferred" ways to code different typical solutions to servers side state applications. The source itself resides in the www/shoppingcart directory in the source code tree. A <a href="shopcart.erl">link to the source itself</a> to view from the browser. </p> <h3> The first trick, the <tt>break</tt> statement </h3> <p class="pp"> The source of all yaws pages (including example index.yaws) look very similar in this application, specifically</p> <div style="background: rgb(211, 211, 211)"> <pre> out(A) -&gt; case shopcart:top(A) of ok -&gt; shopcart:index(A); X -&gt; X end. </pre> </div> <p class=pp>All code, including the head containing the link to the stylesheet is dynamically generated. The first function in all code snippets in yaws files is always a call to <tt>shopcart:top(A)</tt></p> <p class=pp>The <tt>top/1</tt> function will check the cookie and if a cookie which is associated to an active session is found, the request is granted, otherwise the login page is displayed by the <tt>shopcart:login(A)</tt> function.</p> <p class=pp>The last item displayed by the login function is the atom <tt>break</tt>. When the yaws server sees the <tt>break</tt>, it will not process any more data from the yaws page being requested. Thus, we can have the login call at the top of a yaws page and still have subsequent html/yaws code on the same page.</p> <h3>Redirect to the requested page</h3> <p class=pp>Since the <tt>login(A)</tt> function is supplied with the Arg of the requested page, the login function will set the path of the requested page in a hidden field in the login form. The code that processes the login form will then issue a redirect to the value of this hidden field if the login in successful.</p> <h3>Ehtml</h3> <p class=pp>The use of the ehtml output syntax makes it more convenient to dynamically generate structured content:</p> <ul> <li><p class=pp> It is easier to get the structure right,</p></li> <li><p class=pp>It is easier to inject the dynamically generated parts in the structure,</p></li> <li><p class=pp>It is <em>much </em> more beautiful.</p></li> </ul> <p class=pp>See the <a href="shopcart.erl">source</a> for a number of "proofs" for this.</p> <h3>The use of the <b>yaws_session_server</b> </h3> <p class=pp>The yaws_session_server is designed to facilitate server side state applications. The yaws application writer is supplied with the following capabilities and services:</p> <ol> <li><p class=pp>Truly random cookie generation. Each cookie can subsequently be used to uniquely identify a session.</p></li> <li><p class=pp>Maintenance of an opaque application state in an ets table. This state is readily available to the yaws page by means of the cookie.</p></li> <li><p class=pp>Old idle sessions are garbage collected.</p></li> </ol> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/style.css���������������������������������������������������������������0000664�0001750�0001750�00000002215�12605311413�014614� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style TYPE="text/css"> body { font-family: Verdana, Arial, Helvetica, sans-serif; color: black; } div.links { background: green; } H1, H2, H4, H5 { text-decoration: none; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; font-variant: small-caps } P { text-decoration: none; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: normal; font-size: small; } .toprow { text-decoration: none; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; } .pb { text-decoration: none; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; font-size: small; } .pp { text-decoration: none; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: medium } A { text-decoration: none; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: normal; color: green; } A:link { color: #0000f0 } /* unvisited link */ A:active { color: lime } /* active links */ A:hover { background: brown } </style> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/shoppingcart/Makefile.am�������������������������������������������������������������0000664�0001750�0001750�00000001021�12605311413�014770� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include @top_srcdir@/include.mk MODULES = shopcart.erl EXTRA_DIST = $(MODULES) EBIN_DIR=@top_builddir@/examples/ebin EBIN_FILES=$(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/man.yaws�����������������������������������������������������������������������������0000664�0001750�0001750�00000002371�12605311413�011724� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> out(A) -> L = case queryvar(A,"page") of {ok, Page} -> %% only allow regular chars in Page case lists:all(fun(C) -> if $a =< C, C =< $z -> true; $A =< C, C =< $Z -> true; C == $_ -> true; C == $. -> true; true -> false end end, Page) of true -> os:cmd("env LC_ALL=en_US.ISO-8859-1 man " ++ Page ++ " | col -b -p -x"); false -> "illegal character detected in query arg" end; undefined -> "no man page found in query arg " end, {ehtml, {html,[], {'div',[{class,"man"}], {pre,[], L}}}}. </erl> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/websockets_example.yaws��������������������������������������������������������������0000664�0001750�0001750�00000007532�12605311413�015041� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> Host = (A#arg.headers)#headers.host, {abs_path, Path} = (A#arg.req)#http_request.path, EndpointPath = filename:dirname(Path) ++ "websockets_example_endpoint.yaws", WebSocketLocation = Host ++ EndpointPath, Body = html_body(WebSocketLocation), {content, "text/html", Body}. %% this html was copied from the basic example in %% http://github.com/davebryson/erlang_websocket/ html_body(WebSocketLocation) -> "<html> <head> <title>Basic WebSocket Example</title> <script type=\"text/javascript\"> var WS = false; if (window.WebSocket) WS = WebSocket; if (!WS && window.MozWebSocket) WS = MozWebSocket; if (!WS) alert(\"WebSocket not supported by this browser\"); // Get an Element function $() { return document.getElementById(arguments[0]); } // Get the value of an Element function $F() { return document.getElementById(arguments[0]).value; } var client = { connect: function(){ this._ws=new WS(\"ws://" ++ WebSocketLocation ++ "?extversion=\"+$('extVersion').checked + \"&keepalive=\"+$('keepalive').checked + \"&timeout=\"+$('timeout').value); this._ws.onopen=this._onopen; this._ws.onmessage=this._onmessage; this._ws.onclose=this._onclose; $('msgs').innerHTML=''; }, _onopen: function(){ $('connect').className='hidden'; $('connected').className=''; $('options').className='hidden'; $('phrase').focus(); client._send('client-connected'); }, _send: function(message){ if (this._ws) this._ws.send(message); }, chat: function(text) { if (text != null && text.length>0 ) client._send(text); }, _onmessage: function(m) { if (m.data){ var text = m.data; var msg=$('msgs'); var spanText = document.createElement('span'); spanText.className='text'; spanText.innerHTML=text; var lineBreak = document.createElement('br'); msg.appendChild(spanText); msg.appendChild(lineBreak); msg.scrollTop = msg.scrollHeight - msg.clientHeight; } }, _onclose: function(m) { this._ws=null; $('connect').className=''; $('connected').className='hidden'; $('options').className=''; } }; </script> <style type='text/css'> div.hidden { display: none; } #msgs { margin-left: 25px; background-color: rgb(211, 211, 211); width: 500px;} </style> </head> <body> <h1>Basic Echo Example</h1> <ul><li>Sending \"bye\" closes the connection.</li> <li>Sending \"say hi later\" sends \"hi there!\" asynchronously.</li> <li>Sending \"fragmented message\" sends \"frag1frag2frag2\".</li> <li>Sending \"something\" does nothing.</li> <li>Other messages are echoed.</li></ul> <div id=\"options\"> <input id='extVersion' type='checkbox'/> Use extended version<br/> <input id='keepalive' type='checkbox'/> Enable keepalive timer<br/> KeepAlive timeout (in milliseconds) <input id='timeout' type='text' size='5'/> </div> <div id=\"connect\"> <input id='cA' class='button' type='submit' name='connect' value='Connect'/> </div> <br/> <div id=\"connected\" class=\"hidden\"> Say Something:&nbsp;<input id='phrase' type='text'/> <input id='sendB' class='button' type='submit' name='connect' value='Send'/> </div> <div id=\"msgs\"></div> <script type='text/javascript'> $('cA').onclick = function(event) { client.connect(); return false; }; $('sendB').onclick = function(event) { client.chat($F('phrase')); $('phrase').value=''; $('phrase').focus(); return false; }; </script> </body> </html>". </erl> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/compile_layout.png�������������������������������������������������������������������0000664�0001750�0001750�00000037442�12605311413�014006� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR����­���ñ¹k³���sBITÛáOà��� pHYs��Ð��й‹çŸ�� �IDATxœíÝiTg¢7ðêH°AYdéÆÁØ"z£&÷æd<Nh–&€ä Æ9žˆA#"É\5€W#wL\“k$™(£‚Q0+ˆ' KŸÑ0ˆ`ºQÑ«,6Ý]ï‡ÊÔ[饪š¥áÿûT?T=K5ÖŸ§—z’$ ���Ë„#Ý��íÄô¦�0z×=NÔé™Yó©�€Q/@��D��plTTWWgff†††Rõz}FF†———‹‹K\\\ww7U.rss¥R©X,fš™™YSS3Èn��ÀÐHTèõúòòòÔÔT©Tš@’d^^õ£œœœêêj¥R©V«œœÒÓÓé£*++•J¥N§cV•——G’d||¼L&Û¸qcyy¹^¯Ìx��Àæ$IRo2óü$@rròùóç¥RilllLL =Ÿ ‡……¡V«åryGGA ½½}Ê”)¿¶*5wõêÕ‚‚‚ÂÂÂÖÖÖ+V|ðÁ6�€|Ê*ÔésîgD$ …B­VÛßßo:P©Tr¹œ ’$ ó)¡sÂ,N§Óé´Z­P(‰DÖö ��†ŽÕ³ ‚ Ã¥K— Î;çèè¸råÊØØØùóç!•J¿ÿþ{ãf~; VUUœ={V«ÕÆÄÄÄÆÆ.Z´H(Ä›í�0T0«° uºLÕÕÕÔ GW¯^%"''ç»ï¾;pà@```CCCvvö§Ÿ~JXŽŠÐÐÐØØØØØØˆˆ›Œ �€¢Â*¶‰ #ƒa÷îÝGŽioo ËÌÌ\µja9*��†¢Â*C��£¢Â*#yc��°#ˆ ��à€¨���ˆ ��à€¨���v;vìx饗Ø÷‰ŽŽÞ¹sçðô�`<Õ–5úúEWW×Ì™3ÿñ0ïª×ëé’ÖÖÖðððŸþY"‘ kwÀàòV±¿Ëž8q"66–™?ýô“N§sttüá‡èB©TùÉ'ŸŒD�Æ aо¾¾”””‰'Nœ8qíÚµ}}}T¹Ñú©¿~9ð_ÿ¥ZTTôüóÏ3÷<qâÄêÕ«Oœ8Á,‹‹»pá{g°T��OÃúÔ¦M›®]»vüøq’$fÏžý—¿ü…°|Û£r//¯ÚÚZ///êá£GüüüjjjfÏž­R©œœœ¨ݾ};,,L­V³t¦ªªª°°°°°°§§'&&&&&fñ⟩-À˜‡ ¬27öðóó+++ "¢¡¡á™gžQ©Tï¨pppèééqpp ž9sæàÁƒ¥¥¥A,]º4%%å…^ ~¤×ëµZ-Ÿ^a© €qQa•x¯B­VO›6Úž>}ºF£±êpww÷®®.ú!õêµ½zõjækP]]]îîî¦5þ…Yˆ¥2��ØY½´Ñ`x{{߸qcÆŒA477{{{ÿÚ ±¸··×ÙÙ™ ˆ;wîX:|öìÙJ¥rÙ²eAh4š/¾ø¢¨¨())‰®D­VSuVUUÍ™3Ç´æ_FKe¼ÿþûX*�À¬a½2*Š´´´ÎÎNF“ššªP(¨r¹\¾wïÞžž•JµnÝ:z‰DÒÐÐ@?ŒŒŒüì³Ï¨í¿ýío¯¼ò ɘ˜H­AÄÉ“'—/_ÎÞ™ÄÄD¡PxòäÉ–––ýû÷/Y²9�`ý‡69ôz{{“““ÝÜÜÜÜÜ’““{{{©r¥R.‹Þ{ï=º3YYY®®®ôÃ;wîxzz¶··“$)—Ë¿ýö[fåeeer¹œ$É›7oº»»ß½{wF�vÇèì¨5ª¿‚gjÇŽW¯^=uêË>ÑÑÑsçÎýóŸÿ<l½�;‚·µ­‚¥�`<BTXÅþ¾­ ��#Q����ÀQ����ÀQ����ÀQ����ÀQ�0pf—6 ‚$É-[¶¸»»{xxdddŒ»í™-7[§““ÓâÅ‹¯\¹ÂÒº ÇÂQ�0pÌ{ê1=zôÒ¥Kõõõµµµeee~ø!{¹Ùj»ººV¬X7„à‰Æ;Ë�Œ8£  ­ê4*Y¸paII µ]RR²hÑ"örKµ=xðÀÉÉéîÝ»“'Oîìì¤ µZ­§§§é@t:ÝÖ­[=== ÅÇ©ò‹/†……988Èd²#GŽX;4ÂNgÌ9—­¶�l¨®®nÞ¼yÔvDDD]]{¹Y===‡š?¾»»»B¡8|ø0U^ZZº`Áf¨På999ÕÕÕJ¥R­V;99¥§§S剉‰Û·oðàAEEEUUÕ�†c—w–e®¹m«m�'†â⦑HÔßßO-˜f0u:K¹¥ººº–——Ï;÷ÆO?ýôÏ?ÿìàà°nݺgžyæÅ_4j700°¸¸8,,Œ µZ-—Ë;::‚Édiii111R©t�C#ìtVÁ<5¶Ú�°!WWׇRÛ<xüñÇÙËPs…žžž¬¬¬´´4‚ ¦NºpáÂüü|ƒÁPVV¶bÅ Ó£T*•\.‹Å"‘ÈÇÇG£ÑPågΜ)))‰ˆˆJ¥çÎÀpì2*��F¹°°°êêjj»¦¦†úKŸ¥Ü,ggçäääü‘zøæ›oþÏÿüÏ÷ß¿xñâÇ{Ìtÿ)S¦´´´èt:½^O’¤Á` ÊçÏŸþüùÎÎÎ#GŽüéOÀp��¶—˜˜øÖ[oýòË/ííí™™™IIIìåfõöö9rdÚ´iÔÃyóæM˜0!===!!*‘H$ ôþëÖ­KII¹~ýºN§«««£?:¥P(êëëµZ­Á`Ðëõ‰O@Àxbt´amÌ ÃæÍ›%‰D"IOO7 ìåfë‹ÅUUUô.\¸ “É裲²²\]]évõz}NNŽL&spp˜3gÎéÓ§©ò“'O†„„ˆÅâY³f}ùå— ]¾­ �0`v½`êÁƒU*Uvvö°µˆµµ`<²ß¨¸ÿþ“O>YRRâëë;lÚñ' Æ¶S§Ny{{ø;£öË"ÃÐ1k›µç À”@ ˜4iÒ† †3'hvcû¦+[¶l),,4í¤ÀÄvcd óèÆöÉ„±$IN7°Ï/ ž]F…Ùw“ˆ±rÓ•[·n-\¸ÐìØßOK†ytcûdØ�i·Ÿ€2í³}Ýt¥··799ÙÍÍÍÍÍ-%%¥··—dýl†¥çˆ ˆýû÷ˆD"ænÍÍÍÏ?ÿ¼«««““Ó²eËÔj5½ÿ¡C‡¨ÏH„‡‡_¾|™*ïééILLtqqñööÞ³gÙæ´ZmZZÚäÉ“%ɾ}ûXB’d___RR’i…–ΘÙÁZê­Ùž02[›¥.q6Çç䀽`ùW¦¨e—³ Kìë¦+™™™íííMMM---o½õñ¯äfÖÏGee¥R©4º=@TTTjjªF£Ñh4¿ûÝï¨/|RJJJ.]ºtïÞ½èèèäädªðí·ßîêêjii¹råJEE…Ù†¶oß^[[«T*›››[[[YBUØÙÙÙÒÒrùòåÒÒRºKg̳½5ÛN–ºÄÙŸ“0–‘chV! ©ï(’$©×ë©¿²YÊj£¹ººÖÔÔ$ÙÜÜ ÕjI’|íµ×òóóMÛ•ÉdµµµÔvGG‡··7µ-•JsssoÞ¼i©ÿ¾¾¾Ôöµk×|}}-Ë´‡Ì§Œ ˆööv–ÓB’dww·§§'½ÃíÛ·ér±XLmûùù]¿~Únjj2[¿¿CCÏøùù555QÛÔ·„¨mKgÌh°ì½5Û‚kVa©KœÍñ99`/Lÿ‹1nnn÷ïß§¶ïÝ»'‘HØËÍÖÖÓÓ“››ûôÓOS_|ñÅ?þX¯×‡„„Я1¤n·"‰¨ûQwï"I²²²2**jòäÉÔÛÔFD"‘N§£¶ûûûé«KTð)§þðÃK–,™0aõüÒ³´¿QÌ6GÝéŒç@,Uh錙íKoM{Âç(³]ð`V¡NÔ˜zʾnºâíí}ãÆ j»¹¹ÙÛÛÛê³zá…Ö¯_ëÖ-ƒÁ@%%ûþÞÞÞ---Ô6½adÊ”)ÍÍͦšÈ”)S˜åÌJÌž1«˜í M,÷ööRÛwîÜae¶Kœøœ€1lLE…}ÝtE¡P¤¥¥uvvj4šÔÔT…B1Øñ› ÄÑÑÑÙÙ¹¥¥eíÚµœû¿üòËo¼ñÆíÛ·;;;™ol0­^½úõ×_¿uëÖ½{÷RSS©BK‰‹‹Û¸q#]NWbéŒYÅlOhr¹|ïÞ½===*•jݺut¹¥.qâsr�Æ2Ò_€2žnºÂüàPrr2ýÁ!KÏ…ÙçÎtúáùóç§OŸ.‹§NzðàAÎý»»»ããã½¼¼víÚåàà`Ú­V›ššêáááîî¾ÿ~öôöö&%%Q2?5d錙핥ޚí ýS¥R.‹Þ{ï=ºÜR—lrrÀ^˜½z€%Ô‰Â=¸ ÿMWFܵkמ{î9«^¢?prìýÞØcDàÆ¼Ü¿ÿÀëׯéŽ ‡ 6ܽ{·££ãÍ7ßŒŽŽéîŒ.890ž!*ØŒìMW†_HHHhhhPP››ÛÎ;Gº;£ NŒgx �Ƽ�e¼���¼ *��€ÃXˆŠ¿ƒôðw`xZÁ;âÏ)�0ÙeTà:20J¥288x¤{�öÇ.£¦¨¨hùòå#Ý �°?ö¿® þÛeà>èèè8wî\z;½^Ÿ‘‘áåååââ×ÝÝÍYyuuufffhh({  77W*•ŠÅbæá¡¡¡™™™555œ ݸq#::úñÇì±ÇþøÇ?j4ºf³cyôèÑ«¯¾:aŸ½{÷rÖo:‚ Š‹‹©¨ºq ‚]»vyxxøøøœ;wn×®]“&Mòññùꫯ8n¶éªª*ÿ¿þõ¯ü»ýùçŸÏš5ËÑÑ100ðèÑ£|Î�°³¿¨ Í­è`vžë"èõúòòòÔÔT©Tš@’d^^g f—ˆÈËË#I2>>^&“mܸ±¼¼ÜìÝŸˆ-&Á¹ÐûX4Mccã’%K†t\A¨Õê¶¶¶ìììøøxµZÝÚÚš½iÓ&Λ6]PPyøðá 6ðï6çJ!�`5Ò>ïeôÐì|ÖEX³f§§gDDDvvv}}½ÑO-Õ@p-Q__Ÿ••áéé¹fÍöáð\LÂìB üÇrüøñU«V õ¸‚¸sçI’}}}Ìm³k„ ܨé={öøùùQ ‡XÕmΕB`œ3º�;êDÙ߬¬I“&Q...ôŸ¥*•J.—S«#øøøÐ¯u0Q«&hµÚþþ~Ó¿”Yj˜2e Kt:N§ÓjµB¡P$™îðã?>õÔS®®®`„ ·oßfKGGÇÔ©S©mú®·V¥¨¨(22r¨ÇE„‡‡ANNNÌmº?,7júðáÃIIIsçÎ¥KxvûÌ™3%%%R©ôܹs,Ã�¾È11«0û0  ­­³6úE™L´uëÖÊÊJö,µXYY¹uëÖ   ê…šŠŠ zõ=#þþþ§Nêêꢓ ¸îlêïïÏ9«`‹V«•H$ôòÚC7.f f·ù¼­­mÆŒ{öì¡ yv›vñâE³?‚ñÌèìì8*$ɵk×臖.pÙÙÙË–-kjjêïﯭ­U(œ5WUUeddÌœ9“½K-Μ9sÛ¶mÕÕÕœ Mš4©   ¯¯¯¹¹ù¥—^⌊-[¶DFFj4µZ½lÙ2>Ïs,ß|ó µ0øP‹3*¬¸J¥ ÉÉɱªÛ/¿ür]]Ý£GŠŠŠè¸�hˆ «ØqT­aéÇg]v–j`ŸÖðaíb–ZàiãÆ;wî†qqF…µÿå—_BCC©Îóì6çJ!0Î!*¬B(Ü.p\ÎÏÏéŽ�Œ<Ü.Ð*¿~?Q�ã ¢Â*¸³,��ð‚¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���#Ì%Ñ�`²}T(•Êàà`›W ��#ÅöQQTT´|ùr›W ��#e°QQ]]™™J—SQ¡×ë322¼¼¼\\\ââ⺻»©Ann®T*‹Å̪BCC333kjjÙ%��°­D…^¯///OMM•J¥ $IæååQ?Òh4K–,!"''§ººZ©TªÕj''§ôôtº†ÊÊJ¥R©Óé˜Õæåå‘$/“É6nÜX^^®×ë14��° I’ÔË$Iò9 99ùüùóR©4666&&†9Ÿ â£>*..>}ú4AÅÅÅaaaA¨Õj¹\ÞÑÑA„@ hooŸ2eʯ=Œš¾zõjAAAaaakkëŠ+>øà[Œ�€ ~ûQž×½ñŒ:]bÎýŒˆD"¡P¨ÕjûûûMÿêg¾Q¡R©är9A$I æÓCç„Y:N§ÓiµZ¡P(‰¬í!��Ø–Õ³ ‚ Ã¥K— Î;çèè¸råÊØØØùóç÷÷÷{yy544xyy!•J¿ÿþ{ã&; VUUœ={V«ÕÆÄÄÄÆÆ.Z´H(ùóÀX‚Y…U¨Ó5 ±P(|ê©§rss[ZZ>ýôS@˜˜HDEEEHH•A¬[·.%%åúõë:®®®...޽ÚÄÄD¡PxòäÉ–––ýû÷/Y²9�0 dVaÉo¼áááñöÛoS ÃîÝ»9ÒÞÞ–™™¹jÕ*Âò¬�``VaêtÙ2*‚ƒƒóóóÃÃÃmÐ;�€¡¨°Ší£�`ôCTXeàïU��À¸‚¨���ˆ ��àðÿ¿‚‡›�€Y˜U���1Ï��Àøƒ×Q¬bõ= ��Æ ��€m Q`œÂkïüýúN�ŒxÝÉZx¯�Æ)ÔD–��˜U�À¸†—ß-aκ0«���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���Ãøzä`ØãÙU}U°#£eVñÕW_-]ºÔÙÙyÒ¤IñññÆÚÁ±cǘ%Ÿþ9ÏKƒénT‰Àζp=m”Jepp0˃ÿõÛFKTìÛ·ï7Þ¸}ûöÕ«W'Nœ¨P(PɱcÇôz=ýpÏž=ƒìù/FÛCÑ ¢¢¢åË—³ì`“_?€±2UUUÛ¶m›9s&}=tèL&spp¿|ù²é!ÝÝÝNNNÔöÌ™3·mÛV]]ÍÙA›6múä“O¨‡Ÿ}öÙúõë ‚¸{÷îäÉ“;;;©r­Vëéé©ÑhŒŽ5­ý¡Ù¶,ÕÆ¤ÕjÓÒÒ&Ož,‘HöíÛGööö&''»¹¹¹¹¹¥¤¤ôööRå}}}III...ÞÞÞTQå:nëÖ­žžžÎÎÎ …âáǃlˆ ˆœœwwwooooï/¿ü’½Å‹/†……988Èd²#GŽ˜vÃÒ3n©B‚ öïß ‰xŽÔˆÑ¯I’ÿöoÿVRRÂÒ¦ýú}ž«Ÿ½cžŸ!™UèõúòòòÔÔT©Tš@’d^^ýÓ’’’K—.Ý»w/:::99Ùôð¯¿þzáÂ…Ôv^^I’ñññ2™lãÆåååÌ¿å¬_¿~÷îÝÔÀvìØ‘ššJ„»»»B¡8|ø0µOiié‚ <==9F³mñ±}ûöÚÚZ¥RÙÜÜÜÚÚJfff¶··755566¶´´¼õÖ[TùÛo¿ÝÙÙÙÒÒrùòåÒÒRº’œœœêêj¥R©V«œœÒÓÓÙAjµº­­-;;;>>^­V·¶¶fggoÚ´‰½ÅÄÄÄíÛ·?xð ¢¢¢ªªÊìÍ>ã,C¨¬¬T*•:ŽçH Ö_9FÓØØ¸dÉ–Î0 ø×`ì³a­Y³ÆÓÓ3""";;»¾¾Þ4¦nß¾Mmwww‹Åb£ª««§OŸÞÔÔdT^__Ÿ••áéé¹fÍÓv©Q,_¾üìÙ³gÏžŒŒ¤ ›››´Z-I’¯½öZ~~¾é±ìçÄìC³m™îlÄßß¿¡¡Á¨Ð××·±±‘Ú¾v횯¯/µíççGŸŠ††ºf™LV[[Kmwttx{{²!‚ îܹC’d__s›úÓž¥E©Tš››{óæMKãµôŒ[ª ˆöövúp>#eÿ•;~üøªU«Ø;Cð¯Ø—!ºú1Ìócû“µvíZooï'žxbûöíÿüç?MÛfyXZZ*“ÉÌÎ÷¯\¹²}ûö'žxÂÛÛ{íÚµ¦;PU}ñÅsçÎ={ö×_ͬÿÅ_üøãõz}HHýª‹¥npö“½-öó)‰úûûM u:µÝßßO_ÂŒÊéšÅb±H$‰DB¡ @0Ȇ˜}6»m©ÅÊÊʨ¨¨É“'švÃÒ™´T¡Ñþ|FÊþ+·råÊãdzw†2˜_?°/ˆ >†6*H’¤_ ÉdAAA[·n­¬¬¤Û3ê ½}êÔ)??¿ššæ•••[·n ¢^¨¨¨Ðëõf¥ª2 ÁÁÁ³fÍ2ª¿ªªjÞ¼yß}÷ËŒ„¥ÄìCKm lVÁœ=øùùÑ;›U´µµ±´bmCœQÁÙâÅ‹}||LË-IKíÏg¤¤å_9­V+‘HÔj5{gÈAÿú}ATð1äQÁTUU•‘‘Á|[Û¨+ÔÆ¾}û¤R©é«V½­Í^øôÓOÿþ÷¿/++ãs,Ÿ¨°tûùÌÌÌ\ºti[[[WW׆ ¨ÂM›6EEEi4µZ½lٲ͛7Så[¶l‰ŒŒ¤Ëéš³³³—-[ÖÔÔÔßß_[[«P(ÙgTXjñå—_®««{ôèQQQ‘§§'ËiáY¡Ñþ|Fj„ù+÷Í7ß,X°€³3ƒÿõû‚¨àcX£Â´m³ <Lͦ….\ÉdƒÏ±ƒŒ –_D­V›ššêáááîî¾ÿ~ªùÁ¤äädú%²ÞÞÞ¤¤$ggg///æ' ôz}NNõIž9sæœ>}Ú´?V5Ä–Z<yòdHHˆX,ž5kýq)>§ÎR…Fûó)‹7îܹ“³3ƒÿõû‚¨àƒy~ôÓ-cÌÁƒU*UvvöHw†Oppp~~~xxøHwFæ÷dÇÃÕo`¨³DŸñ÷ïßòÉ'KJJ|}}Gº/�0Â|0£b\¬­-D"Ñ��0.¢5�� Æh¹��ŒZˆ ��à`ßQ1R÷ýå·=Ý;uê”··÷èé� Œ=EEhh(ûªÄ]%‡îbgi¥’$·lÙâîîîáá‘‘‘ÁüŒ³Ùòê‹ø–-[¨»} i+�0Ôì&*~úé'NçèèøÃ?Œt_lÉÒJ G½téR}}}mmmYYÙ‡~È^>:ݺu‹¾K+�ؽáÿ µþô§?½óÎ;»wï~íµ×èB‚ñm[ÒÜ70--ÏÐÓÓ“˜˜ÈsÓj‰Á­Á` s¥„… RK,$YRR²hÑ"ör&‚ þû¿ÿÛËËËÅÅåÕW_íëë3»h‡é¸¼(…Ùól_¿`0®à—“æù±YÅ£Gþþ÷¿'$$ÄÇÇŸ9sæÑ£Gfw#MnÕÀ²DWWWKKË•+W***èÌ®Ž`Z-1¸5,a®”PWW7oÞ<j;""¢®®Ž½ÜHEEÅ•+WnܸñË/¿üùÏ6»h‡é¸¼(…Ùólö¼€¾œÓ§OÿÇüµý‡?üáïÿ;µMüvVÁÜ °¬qýúuj»©©‰>ŠefµÄàÖ`0Ëh¥¡PHßÄT¯×ÓÓKåFÝ3½}¬ÙE;ŒÆ5àE)X–Á`5Àˆ°£«ßbžû8YË—/ÿ裨íO>ù„ZJˆä¶ZÂ4*Ì>äy¸)Ó•ÜÜÜîß¿Omß»wO"‘°—õÇì¨Mí0êØ€¥à³ Àè¨àÃ΢B­V‹Å¿ùV¹X,îèè ùÍ*Ì.ÏàëëkvVÁsKynÄìJ ƒ|¯‚9jjÛtÑ£Ž xQ >Ë`�Œˆ >ì,*Þ}÷ÝÕ«W3Kþó?ÿóÝwß%Í%„D"¹ví½§¥åÒÒÒ¢¢¢:;;5MTT}¸¥ÕŒªµ<×``²´R¡C‡.\ØÞÞ®R©ž|òÉcÇŽ±—õ'22R­VS£NOO§d´h‡Ñ¸¼(Ÿe0�FDvr¹üÛo¿e–”••ÉårÒ\Tdee¹ººÒ--ÏÐÝÝO­±k×.ªÜÒêFÕZŠ žk0k„Z)Á`0lÞ¼Y"‘H$’ôôtz™ KåFuîÞ½›únVÜã��¹IDATTRRsX£E;ŒÆ5àE)ø,ƒ0z *ø`žŸñrr×®]{î¹çš››Gº#Ëv�¸ 9?Ì›ÛLJe‡Â† îÞ½ÛÑÑñæ›oFGGtw†Ãýû÷8°~ýú‘î�Ø™ñ!!!¡¡¡AAAnnn;wîéî 9@0iÒ¤ 6`Ñ�°^€€q/@ñ ��À ˆ ��à€¨°%,Ì��c’}D…é%˜*˜C•;vŒ¹ÿçŸ>Rë �Ø;ûˆ K˜_1úÚȱcÇôz=½'u§q���ûŽ O=õÔ©S§¨íóçχ……ñ<°¿¿Ó¦Mžžžîîîï¾û.UØ××—’’2qâĉ'®]»¶¯¯*ôèÑ«¯¾:aŸ½{÷Ò•èõúŒŒ êûÒqqqÝÝݶ�Àp³Q±~ýúÝ»wSóŒ;v¤¦¦ò<pûöíµµµJ¥²¹¹¹µµ•*dY÷¢³³³¥¥åòåË¥¥¥t%, W��Øûø^…Ùw˜}¦n—mô0**êÕW_%âÿ÷‹ŠŠè}Œv6PRRb´ˆ·ŸŸ_YYYPPA Ï<óŒJ¥"Âßß¿¬¬lÆŒA466†„„P5SSµZ-—Ë;::u �Àvð½ >˜ß«°›¨0ê¡Ùl0zøå—_nÛ¶M§ÓíÛ·ïÙgŸåb±¸¯¯Ïô¶ç=‰DAèt:gggj• £r궃AÐ$I @`0lq&�À|Œ—¯à-]ºôáǃáÙgŸåÔ”)SLoèíí}ãÆ j»¹¹ÙÛÛ›Þ™Yά¤¥¥E§ÓQ+Ö!'�À®å¨ ÿüç?­:jõêÕ¯¿þú­[·îÝ»G¿Ã¡P(ÒÒÒ¨õ-RSS U·qãFºœ®dݺu)))ׯ_×étuuuqqq¶�ÀðËQÁÂè{Lÿõ_ÿ*—˧M›6uêTª0++ËÛÛ{ÆŒAAAþþþï¼óU¾cÇOOO™LöÄO<óÌ3t%[·n}ê©§ž}öY—øøøØØØá�ÀP°÷*��lïUð1^Þ«���›@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T�� ÖW_}µtéRggçI“&ÅÇÇk4ªœ$É-[¶¸»»{xxddd$É^Î$ø''§Å‹_¹rÅRë`(Å„¨��¬}ûö½ñÆ·oß¾zõêĉ U~ôèÑK—.Õ×××ÖÖ–••}øá‡ìåFH’$I²««kÅŠqqqÃ4$�À¸1¤W¿îîn'''j{áÂ…%%%ÔvIIÉ¢E‹ØË:Io?xðÀÉÉéîÝ»“'Oîìì¤ µZ­§§§éXt:ÝÖ­[=== ÅÇ©ò‹/†……988Èd²#GŽp„Y'f��¶ôõ×_/\¸Ú®««›7oµQWWÇ^nVOOÏ¡C‡æÏŸïîî®P(>L•—––.X°€*TyNNNuuµR©T«ÕNNNéééTybbâöíÛ<xPQQQUU5±ñLK�€1`è®~ÕÕÕÓ§Oojj¢ …B½^Omëõz‘HÄ^n©“®®®555$I677hµZ’$_{íµüü|ò·ó’$e2Ymm-µÝÑÑáííMmK¥ÒÜÜÜ›7oò óü`V�`ß~ûíÊ•+óóóg̘A•¸ºº>|øÚ~ðàÁã?Î^n„ºL÷ôôdee¥¥¥1uêÔ… æçç †²²²+V˜¥R©är¹X,‰D>>>ô{ìgΜ)))‰ˆˆJ¥çÎÈy† �À0W¿S§NùùùQûÓlõ^ÅÇé÷?ªªªæÍ›÷Ýwß­Y³ÆtO’$ÚÚÚXºzñâEÎ1Ïf��ƒõî»ïnÙ²å믿ž;w.³<11ñ­·Þúå—_ÚÛÛ333“’’ØËÍêíí=räÈ´iÓ¨‡óæÍ›0aBzzzBBU"‘Hèý×­[—’’rýúuNWWWGtJ¡PÔ××kµZƒÁ ×ë2NÎx�3l~õ3½¨>xð€$IƒÁ°yóf‰D"‘HÒÓÓ µ¿¥r³uŠÅ∈ˆªª*úG.\ÉdôQYYY®®®ôXôz}NNŽL&spp˜3gÎéÓ§©ò“'O†„„ˆÅâY³f}ùå—<Em èI��;ÄüΚ=^ý<¨R©²³³‡´ê,QçQ�ãŽ]GÅýû÷Ÿ|òÉ’’__ß!mˆâ!m ��lH ˆD¢ uNAT��Ø‘šáP��ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀQ����ÀALýO Œl?��`Ô¬��8H’é>��Œ�¼šÂ•˜U���„*�ŒGxAÅ*˜U���‡_gX�'ð…Uð^��ð"ÎÆ|à �F \ŽØ1§_˜U���D��p`TTWWgff†††Rõz}FF†———‹‹K\\\ww7U.rss¥R©Xü›WºBCC333kjjÓu��VD…^¯///OMM•J¥ $IæååQ?ÊÉÉ©®®V*•jµÚÉÉ)==>ª²²R©Têt:fUyyy$IÆÇÇËd²7–——ëõz›Œ��lŽï‡e“““ÏŸ?/•Jccccbbèù%00°¸¸8,,Œ µZ-—Ë;::‚íííS¦Lùµ1“·µ¯^½ZPPPXXØÚÚºbÅŠ>øÀV�0‹~·ok³£Nu–ø~J$ …B­VÛßßo:P©Tr¹œªÔ`00ß7§sÂ,N§Óé´Z­P(‰DV ��†‡éj0.]ºTPPpîÜ9GGÇ•+WÆÆÆÎŸ?Ÿ ©Túý÷ßûûû×þÛiý°ªªª  àìÙ³Z­6&&&66vÑ¢EB!Þc€!‡YOÌYÅ�OYuu5õÂÑÕ«W ‚ÈÉÉùî»ï8ØÐÐýé§Ÿ–£"444666666""ÂFƒ�àQÁ“ ¢ÂˆÁ`ؽ{÷‘#GÚÛÛÃÂÂ233W­ZEXŽ �€‘‚¨àÉöQ�`/<1£o���D��p@T���D��p@T���ûˆŠ;v¼ôÒKìûDGGïܹsxú�0®ŒÆ}ý¢««kæÌ™ÿøÇ?˜÷ ÕëõtIkkkxxøÏ?ÿ,‘H†µ»�`WðaYžììò'NœˆeæÄO?ý¤ÓéøáºP*•FFF~òÉ'#ÑG�€±l8¢¢¯¯/%%eâĉ'N\»vm__Un´:õþ/ýÓ¢¢¢çŸž¹ç‰'V¯^˜˜xâÄ fy\\Ü… Ø;ƒ¥2��¬5±M›6]»víøñã$I&$$Ìž=û/ù aù¶Få^^^µµµ^^^ÔÃGùùùÕÔÔ888Ìž=[¥R999Q?º}ûvXX˜Z­féLUUUaaaaaaOOOLLLLLÌâÅ‹qS[€ñ/@ñ4Ü7öðóó+++ "¢¡¡á™gžQ©Tï¨pppèééqpp ž9sæàÁƒ¥¥¥A,]º4%%å…^ ~¤×ëµZ-Ÿ^a© €ñ QÁÓp¿W¡V«§M›FmOŸ>]£ÑXu¸»»{WWýzõ‰Ú^½z5ó5¨®®.wwwÓÿÂ,ÄR��<ñ]Úh0¼½½oܸ1cÆ ‚ š››½½½m[,îííuvv&âÎ;–Ÿ={¶R©\¶lAæ‹/¾(**JJJ¢+Q«ÕTUUUsæÌ1­ù·ƒÑRï¿ÿ>–Ê��`7—H…B‘––ÖÙÙ©ÑhRSS U.—Ë÷îÝÛÓÓ£R©Ö­[Gï/‘H臑‘‘Ÿ}öµý·¿ýí•W^!©µ1‚8yòäòåËÙ;“˜˜( Ož<ÙÒÒ²ÿþ%K– '��x!‡Rooorr²›››››[rrroo/U®T*ÃÃÃÅbq@@À{ï½Gw#++ËÕÕ•~xçÎOOÏööv’$årù·ß~ˬ¼¬¬L.—“$yóæMww÷»wïéX�ÀÞ Ïuo `ž%ûx{gÇŽW¯^=uêË>ÑÑÑsçÎýóŸÿ<l½�{„·µyÂÒF�0~!*x²³ok�ÀÈBT���D��p@T���D��p@T���D��p@T���D��p@T���D��p@T���{Š æ2v¶Ú��Nö��0"p3^�_pržpr��°¢��8 *��€¢�`€ÿbTN’ä–-[ÜÝÝ=<<222è7E,•›­ÓÉÉiñâÅW®\ai݆ca‡¨�� ’$Í^î=zéÒ¥úúúÚÚÚ²²²?ü½Ülµ]]]+V¬ˆ‹‹ÂX‹„qãäÉ“^^^~ÒGíoË0tÌÚ&Fí¹çl~Ý3­jáÂ…%%%ÔvIIÉ¢E‹ØË-ÕöàÁ''§»wïNž<¹³³“*Ôjµžžž¦pN·uëVOOOggg…BñðáCªüâÅ‹aaa2™ìÈ‘#V‹®ÜžfC4×;vì³äóÏ?ŠiÝè™TnÙ²¥°°ÐôlL i7FÖ0nlŸL0UWW7oÞ<j;""¢®®Ž½Ü¬žžžC‡ÍŸ?ßÝÝ]¡P>|˜*/--]°`3T¨òœœœêêj¥R©V«œœÒÓÓ©òÄÄÄíÛ·?xð ¢¢¢ªªjPãŸ3#δ·‡^¸pa{{»J¥zòÉ';Æ^nTÛüùóu:]òïÿþïCqBè:»»»wïÞƹçƒaÀíŽÚß–a蘵MŒÚs5ÎÙüºgZ•P(ÔëõÔ¶^¯‰Dìåf»G„««kMM I’ÍÍÍZ­–$É×^{-??ß´]™LV[[Kmwttx{{SÛR©477÷æÍ›—QÙÓ/´io9×Û´iÓ'Ÿ|B=üì³ÏÖ¯_O7ÑÛÛ›œœìæææææ–’’ÒÛÛKµÿþ€€�ê™¶4ï³Ôíá™Tší<Ëß–~ ŒKïÖÜÜüüóÏ»ºº:99-[¶L­VÓû:tH&“988„‡‡_¾|™*ïééILLtqqñööÞ³gÙæ´ZmZZÚäÉ“%ɾ}ûØŸ…¾¾¾¤¤$Ó ­z:,õÖlO˜G™­ÍR—8›ãsrÀV†!*ÜÜÜîß¿Omß»wO"‘°—›­­§§'77÷é§Ÿ¦¾øâ‹ü±^¯ ¡ÿ93‹Å"‘H$ …B‚ U^YY5yò䀀�êþãSQ1Èg¥¹¹ù‰'ž0 ƒaîܹtiiiÏ=÷œZ­îèèøÃþ°iÓ&ú(…BA_åwîÜùì³Ï¶µµýßÿý_RRÒúõëYºÝÝݽgϞŋ“$ùú믿óÎ;Tù_|±|ùrÓZª|òäɧOŸîëë»yófrr²i‹,7Ý™½œ9Xz·°°°ÒÒÒžžžû÷ï§¥¥½òÊ+ô«V­jkkëîîÞ±cÇüùó©òM›6EEEi4µZ½|ùr³ÍmÛ¶méÒ¥­­­wïÞMMMeÈ›o¾©Ñh:::–-[FWhÕÓa©·f{–ºÄÙŸ“¶2 Qa«÷*>|èääDmWUUÍ›7ï»ï¾[³fÙvÚÚÚXúyñâEžƒ"Ç^T r®G’äòåËÏž={öìÙÈÈHf¾¾¾Ôöµk×|}}é£ÚÛÛéJ,ÍûŒæI%KçÍîO˜0;X³‡www{zzÒ;ܾ}›.‹ÅÔ¶ŸŸßõë×©í¦¦&³õøûû744ðˆŸŸ_SSµÝÐÐ@WÈóé`ï­ÙžpF…¥.q6Çç䀭 CT:tÈì«ß–ÊÍÖÖÓÓ³oß¾ÐÐPúGO?ýôïÿû²²2ê¡D"¹víýÓìììeË–555õ÷÷×ÖÖ* ªüå—_®««{ôèQQQýï”ç¸ÆTT ~®÷Å_Ì;wöìÙ_ý5³ ‘HD¿ÑßßOÿÃæ9ï3Ûía›Tòì¼iÙËé‡?üðÃ’%K&L˜@ý ѳ´¿QÌ6'‰úûûyÄR…V=,½5í Ÿ£ÌviÀÂP°aT˜ýëŠ$IƒÁ°yóf‰D"‘HÒÓÓéw-•›­S,GDDTUUÑ?ºpá‚L&£ÊÊÊruu¥ÛÕëõ999ÔË›sæÌ9}ú4U~òäɱX<kÖ¬/¿üÒÚÑý¦Wüq¦½ü\Ï`0Ïš5˨ ___æ‰~~~fûÀ9ï3:dx&•<;o¶‡,åôCÿS§Nuuu †û÷ïs^ }}}<«0;³Â[õt°ŒŽeV!‹{zz¨íÛ·o3âœU˜­ÏÉ[±ù¬bؼÿþûÛ¶m¶æÆZTØd®g¶ù ò²eË6oÞlö(Kó>³uÛ¤’gçÙO…i9ýpÒ¤I}}}ÍÍÍ/½ôçÕ0---**ª³³S£ÑDEE™m.33séÒ¥mmm]]]6l`È–-[¨7¨rºB«žK½5Ûú§;vìèîî¾uëÖªU«èrK]²ÉÉ[±Ó¨¸wïÞÌ™3U*Õ°µh¯Q1Ds=–Bægo’““™Ÿ€bîoiÞg¶óÃ6©äÙyÓaKW·óçÏOŸ>],O:õàÁƒœûwwwÇÇÇ;;;{yyíÚµËÁÁÁ´Z­655ÕÃÃÃÝÝ}ÿþýìéííMJJ¢*d~jˆçÓÁÞ[³=¡ªT*ÃÃÃÅbq@@À{ï½Çü…1Û%›œ°{Œ ‚ D"ÑÁƒ‡¹Qú,á¾í#ïàÁƒ*•*;;{¤;2|®]»öÜsÏ577tGF#œœ¡†õ*xÂz£Èýû÷8@}™cÌÛ°aÃÝ»w;::Þ|óÍèèè‘îÎè‚“£¢b$ ‚I“&mذÁ××w¤û2BBBBCCƒ‚‚ÜÜÜvîÜ9ÒÝ]pr`4ÃD �Ƽ�Å^€��+ *��€ƒGÅˆßØyø;0<-Žà‰ñç�̲§¨Àud`”JeppðH÷�ì˜=E LQQu³R�€±›¨ ¦F«³>|800ÐÑÑqîܹôºrz½>##ÃËËËÅÅ%..®»»›³òêêêÌÌÌÐÐPöAnn®T*‹ÅÌÃCCC333kjj8ºqãFttôã?þØcýñÔh4tÍfÇòèÑ£W_}u„ >>>{÷îå¬ßt,ASQ1tã»víòðððññ9wîÜ®]»&MšäããóÕW_qÜlÓUUUþþþýë_ùwûóÏ?Ÿ5k–££c``àÑ£Gùœ+�àÉn¢‚üíÝ(%%%—.]ºwï^tttrr2UhiÕ@#z½¾¼¼<55U*•&$$$™——ÇYCee¥R©Ôét̪òòòH’Œ—Éd7n,//×ëõfŠŠJMMÕh4æw¿û]ZZûXÞ~ûíÎÎΖ––Ë—/—––Z:9,cÑh4K–,Òq¡V«ÛÚÚ²³³ãããÕjukkkvvö¦M›8nÚtAAAddäáÇ7lØÀ¿Û¶\�ÌÎûŠ arÿ³·þç³\Áš5k<==#""²³³ëëë~j©‚kå†úúú¬¬¬ˆˆOOOúN±–ð\ãÁìJùåøñã«V­êqqçÎ’$ûúú˜Ûf×1¸QÓ{öìñóó£Öó°ªÛ^Æûºî æY²›Y…Y“&M¢6\\\è?KU*•\.§-ðññ¡_ë`¢3Ðjµýýý¦)³Ô0eÊ–þèt:N§Õj…B¡H$2ÝáÇ|ê©§\]]Á„ ¨ûW³Œ¥££cêÔ©Ôö´iÓÌ6Ê>–¢¢¢ÈÈÈ¡AA8991·éþ° ܨéÇ'%%Í;—.áÙí3gΔ””DDDH¥Òsçα �hd³‹'ÂÂ]9òY®€$IúE™L´uëÖÊÊJö,µXYY¹uëÖ   ê…šŠŠ zõ=#Ö®ñ`iýžcÑjµ‰„^õzèÆÅ¬Áì6ÿ·µµÍ˜1cÏž=t!ÏnÓ¬]Æûºî æY²§Sf´ƒ¥ Ÿå ŒTUUeddÌœ9“½K-Μ9sÛ¶mÕÕÕœ Y»Æƒ¥õxŽå›o¾Y°`ý£¡gTX5p•J’““cU·¼*$Œ7ˆ žì5*Œr°tã³\;K5°Okø°vKëð´qãÆ;wø8£ÂÚÿòË/¡¡¡Tçyv{À«BÂxƒ¨à‰y–pÛ¬±,888???<<|¤;0Šàv<1oˆS�ã ¢‚'ÜY��¬€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���ˆ ��à€¨���#ôJè��0ÊÙ,*”Jepp°­j�€ÑÃfQQTT´|ùr[Õ��£Ç�£¢ºº:33344”.)..¦¢B¯×gddxyy¹¸¸ÄÅÅuwwS;‚ÜÜ\©T*‹™U…††fffÖÔÔ t��0´¬ˆ ½^_^^žšš*•JH’ÌËË£~¤Ñh—,YBDNNNuuµR©T«ÕNNNééét •••J¥R§Ó1«ÍËË#I2>>^&“mܸ±¼¼\¯×Ûbh��`¿¾·L’$û~ÉÉÉçÏŸ—J¥±±±111ÌùA}ôQqqñéÓ§ ‚ ,.. #B­VËåòŽŽ‚ A{{û”)S~mX 0jôêÕ«………­­­+V¬øàƒl4F�€ÿþL çuoœ£Nu–Ä\;ÿJ$ …B­VÛßßoúW?ó •J%—Ë© ó“NtN˜¥Óét:V« …"‘ˆ÷p��`hY‘®ƒáÒ¥KçÎstt\¹rellìüùóûûû½¼¼¼¼¼‚J¥ßÿ½¿¿¿qK¿FЫªª Ξ=«Õjcbbbcc-Z$â �0$0«à‰9«°âŠ, Ÿzê©ÜÜÜ–––O?ýT $&&QQQBåAëÖ­KII¹~ýºN§«««‹‹‹c¯611Q(ž<y²¥¥eÿþýK–,AN��Œ*6H×7ÞxÃÃÃãí·ß¦ †Ý»w9r¤½½=,,,33sÕªU„åY�Àp¬‚'æ¬Â§,888???<<Ü&�Rˆ žl��vQÁÓ�ß«��€ñ Q����ÀQ��ø~[�`ŒÁª9üaV��ª�0ᓲVÁ¬��8ü?¨E[Œ_ ����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/ssi.yaws�����������������������������������������������������������������������������0000664�0001750�0001750�00000007543�12605311413�011755� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> box(Str) -> {'div',[{class,"box"}], {pre,[],yaws_api:htmlize(Str)}}. tbox(T) -> box(lists:flatten(io_lib:format("~p",[T]))). ssi(File) -> {'div',[{class,"box"}], {pre,[], {ssi, File,[],[]}}}. out(A) -> [{ssi, "TAB.inc", "%%",[{"ssi", "choosen"}]}, {ehtml, {'div', [{id, "entry"}], [ {h1, [], "Server side includes (with variable expansion)"}, {p, [], "This feature is useful when we are writing applications where " "basically the entire page is dynamically generated but we also " "want to include snippets of either html or, even more typically," " javascript which is almost static, but not quite."}, {p, [], "In particular the case with dynamically generated javascript " "can get syntactically ugly. So instead of generating strings in " "the erlang code for the javascripts and returning them as " "{pre_html, Data} tuples, it is more beautiful to keep the " "javascript functions in separate files and include them with " "the {ssi ...} return value."}, {p, [], "The format of the ssi statement is:"}, {br,[],[]}, box("{ssi, File, Delimiter, Bindings}"), {p, [],"The ssi structure can occur in two radically different places" " but with identical semantics. It can be a return value in the " " out/1 function and it is a specially treated return value " "in ehtml output, here is an example of an odd return value " "from out/1"}, tbox([{ssi, "ssi_ex1", "%", [{"a", "gazzonk"}]}, {ehtml, [ {h1, "a Header"}, {ssi, "ssi_ex1", "%", [{"a", "zippo"}]}]}]), {p,[], "The file ssi_ex1 contains the following text:"}, ssi("ssi_ex1"), {p, [], "And the following ehtml output:"}, tbox({ehtml,[{ssi, "ssi_ex1", "%", [{"a", "Godzilla"}]}]}), {p,[], "Generates the following output"}, {'div',[{class,"box"}], {pre,[], {ssi, "ssi_ex1", "%", [{"a", "Godzilla"}]}}}, {p, [], "And so does the following out/1 function"}, box("out(A) -> [{ssi, \"ssi_ex1\", \"%\", [{\"a\", \"Godzilla\"}]}]."), {p,[], "So this is the way to do when we want to embed dynamic content" " deep inside an ehtml structure, but the content isn't representable" " as ehtml. This is typically the case for dynamically generated " " javascript as well as dynamically generated java applets."}, {p, [], "In the above example, \"a\" can be seen as the Variable " "name whereas \"Godzilla\" can be vieved upon as the value " "of variable \"a\". It is also possible to have the variable " " value be a complete ehtml structure, not just plain ascii " "strings. Here is an example"}, box("out(A) -> E = {ehtml, {h1, [], \"Godzillas baby\"}}, [{ssi, \"ssi_ex1\", \"%\", [{\"a\", E}]}]."), {h1, [], "yssi, Yaws Server Side Includes"}, {p, [], "We have a special version of server side includes that we " " call yssi, yaws server side includes. The syntax for this is: "}, box("{yssi, YawsFile}"), {p, [], "Yssi can only be used as a return value from the out/1 " " function, never nested into a deep ehtml structure." " Yssi, will perform full yaws expansion on the file named " "YawsFile, i.e (possibly on the fly) compile it, execute it and" " subsequently inject the generated output from the YawsFile." " yssi statements can be arbitrarily deeply recursively nested, that " " is a .yaws file which has been included through an 'yssi' " " statement, may itself contain 'yssi' return values in its " " out/1 function(s) "} ] } } ]. </erl> <erl> out(A) -> {ssi, "END2",[],[]}. </erl> �������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/articles.yaws������������������������������������������������������������������������0000664�0001750�0001750�00000003322�12605311413�012754� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(_) -> {ssi, "TAB.inc","%%",[{"articles", "choosen"}]}. </erl> <div id="entry"> <h2>Articles, Books, and Other Resources</h2> <ul> <li><p>The book <a href="http://shop.oreilly.com/product/0636920021452.do"><em>Building Web Applications with Erlang</em></a> by Zachary Kessin, published by <a href="http://www.oreilly.com">O'Reilly</a> in June 2012, provides quite a bit of information about using Yaws.</p></li> <li><p>In his "Functional Web" column in <a href="http://computer.org/internet/">IEEE Internet Computing magazine</a>, <a href="http://steve.vinoski.net/">Steve Vinoski</a> wrote a couple columns about Yaws. Both are available in PDF format:</p><ul> <li><a href="http://steve.vinoski.net/pdf/IC-Yaws.pdf">"Yaws: Yet Another Web Server"</a>, July/August 2011</li> <li><a href="http://steve.vinoski.net/pdf/IC-SSE_with_Yaws.pdf">"Server-Sent Events with Yaws"</a>, Sep/Oct 2012</li></ul></p></li> <li><p><a href="http://steve.vinoski.net/">Steve Vinoski</a> gave a talk entitled <a href="http://www.infoq.com/presentations/Erlang-Yaws">"Erlang Web Development with Yaws"</a> at the <a href="https://thestrangeloop.com/archive/2012">Strange Loop 2012 conference</a>.</p></li> <li><p>There are a number of <a href="http://stackoverflow.com/questions/tagged/yaws">Yaws questions with answers on StackOverflow</a>.</p></li> <li><p><a href="http://steve.vinoski.net/">Steve Vinoski</a> wrote an article entitled <a href="http://www.infoq.com/articles/vinoski-erlang-rest">"RESTful Services with Erlang and Yaws"</a> for <a href="http://www.infoq.com">infoq.com</a> back in 2008. Despite being a few years old, the advice in the article remains relevant.</p></li> </ul> </div> <erl> out(_) -> {ssi, "END2", [],[]}. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/redirect2.yaws�����������������������������������������������������������������������0000664�0001750�0001750�00000000220�12605311413�013023� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> %% redirect2.yaws out(_Arg) -> L="http://www.google.com/search?num=20&hl=en&lr=lang_en%7Clang_sv&q=yaws", {redirect, L}. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/form.yaws����������������������������������������������������������������������������0000664�0001750�0001750�00000002555�12605311413�012120� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> out(A) -> {ssi, "TAB.inc", "%%",[{"form", "choosen"}]}. </erl> <div id="entry"> <h2>POST example </h2> <p>This is a simple example where we get to fill in a series of fields and POST the data by hitting the Submit button at the end. </p> <p> The action is set to the yaws file <tt>/post.yaws </tt> which gets POSTed data in its <tt>ARG#arg.clidata</tt> field. </p> <form method="post" action="/post.yaws"> This is a serious poll. <p>Your favourite programming language? </p> <input name="lang" type="text" size="48" /> <p>Imperative ? <input name="imperative" type="checkbox"/></p> <p>How many tabs to you indent? <input name="tabs" type="text" /></p> <p>Which OS do you use?</p> <ol> <li>Windows 95 pro ultra <input name="os1" type="checkbox" value="w95"/></li> <li>Windows XP beta cracked <input name="os2" type="checkbox" value="xpbeta" /></li> <li>Windows <input name="os3" type="checkbox" value="windows"/></li> <li>Other<input name="other" size="40" /></li> </ol> <p>Your email <input name="contact" size="42" /></p> <p>Submit this POST to get an explanation of how to process the POSTed data.</p> <p><input type="submit" /> <input type="reset" /></p> </form> </div> <erl> out(A) -> {ssi, "END2",[],[]}. </erl> ���������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/process_tree.png���������������������������������������������������������������������0000664�0001750�0001750�00000136502�12605311413�013453� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��Ý��[���·¼¿`���sBITÛáOà��� pHYs��������êe¤�� �IDATxœìÝ{|K÷ÿðÏiÒ6ÑJK[Õjµ¥÷RwöU†›¹ÍfüܦìbfµÍ}3Ê6»c3×aT[C1—ºÓŠ5ªÞ/©&9¿?ÎD$mô’æ“súzþᑜž|Î;Ñæ¼ò9'çͰ,K�@4Íõë×år¹\.ÏÊÊÊÎÎV(¹¹¹………………eeeJ¥R©Tª‰DVVVb±ØÖÖV"‘4jÔÈÞÞ^&“5iÒÄÑÑÑÙÙÙÕÕÕÅÅÅÝÝÝÓÓ3((ÈÊÊŠö³�!cK�øˆeÙ7nœ9sæöíÛiiiׯ_¿sçNvv¶áš...²Ç¤R©D"‘J¥VVV"‘H$i4. py¥´´´¸¸¸°°0???''Çp´&Mš´nÝÚ×××ßßß××·C‡ÁÁÁ+�`*È%�¼qûöí'Nœ:uêôéÓ.\(--å–3 Ó®]»æÍ›{{{·nݺyóæîîî-Z´pvvvrrªËóòòrrr²²²¸9˜ŒŒŒÛ·ogffž?^ûÖÁ0L``àóÏ?Ö¹sç   º>O�hÀK�,ZNNÎï¿ÿŸ T*¹…^^^íÛ·ïСChh¨‡‡GçΆ1gU,ËÞ¾};##ãÔ©SgΜ¹|ùrzz:÷#› 0`РA-Z´0gU� �È%�–¨°°pýúõ[¶l9{ö,˲ ÃtìØ±oß¾/¼ð /¼`mmM»@}*•êðáÃGýóÏ?O:ޱ:´{÷îƒ ¢] �ðr €)))Y²dI\\ܹsç!2™lÒ¤I=zôx饗lmmiWW]*•êСC‡^³fMnn.!ÄÑÑqòäɳfÍrtt¤]�X4ä�‹póæÍÏ>ûlÇŽ¦Y³f£G1bÄÿþ÷?ÚuÕÕ™3göîÝ»qãÆ{÷î1 3dÈ™3g†……Ñ® �,r �eW®\™9sæï¿ÿN:tèĉ(‰h×eJ,ËrÓ';wîdYöÿûßÒ¥KMžº¸^¦�Ì ¹€šœœœO>ùdÆ „)S¦|öÙgÍš5£]TýÊÏÏ_´hѲeËT*ÕСC—-[æíí]÷a³³³×®]{ïÞ½ü±î£�EÈ%�tÄÅÅM˜0!77wêÔ©Ÿþ¹ƒƒíŠÌ§´´tÑ¢E_ýµT*]¾|ùÛo¿]ë¡þþûï•+WnÚ´‰’––æïïoº2€ä�sS©T3fÌX¾|¹³³ó¯¿þú /ЮˆŽsçÎ 6ìîݻÆ Û´i“]õ[^^¾cÇŽ7ß|S»dÆŒ‹/®‡2À¬K�ÌêÑ£G£FÚ½{wXXXBBBÿ~ŠF£yï½÷Ö­[×½{÷ÄÄÄêLýûï¿kÖ¬Y´h‘Þò‚‚™LV?e€ùàêÑ�fõî»ïîÞ½û½÷Þ;vìX%„++«µk×~ÿý÷)))¯½öZEE…‘•;öÆoxzz†’3fܸqãæÍ›>Äg-�^Ã| €ùlذaâĉcƌټy3íZ,ËgŸ}¶hÑ¢yóæ}þùçU­“’’R/3 cooïX5®%¡–L&Ø·Ÿxa°÷Êá7ÀL”Je‹-®\¹"•Ji—cY4M=Ξ={÷î]WWW#«ýüóÏo½õ–ÞòÈÈH—üÇòòòòŸ¦V««“a™LVÍãèèØ¸qc!õ)Ôh4­Zµ"„ܾ}߲ۜ6.Aâ 1í�ŠÍ›7çææ®X±¡Ä••ÕÒ¥K»wïþý÷ߦÑ]mâĉÇÿüóÏ—.]ª]~ãÆ Tõ(–e‹‹‹ó«¦Í1wïÞ½xñbaa¡‘ceeåààPýcoooÉWUIII dY¶šÓQü…PÂÈ�f2räȸ¸¸¼¼<‰DB» ååååêêú÷ßWgå´´´ÀÀ@íÝû÷ï7oÞÜ$e°,[XXXÃ)**Òh4U&‹k”cjô½¤º›6mš¯¯/˲·nÝÒz„†a>øàƒ˜˜˜¹sç~öÙg„}ûöMœ8‘²aÆW^y…['""bÍš5=bfÊ”)6løæ›oΟ?¿uëÖyóæ}úé§ÚÑ$ITTTDD©löbáÂ…+W®T(Ürí º7Þ|óÍ={ö¬_¿~øðá„äääñãÇ—””¬[·îõ×_×Ö³bÅŠ¦M›^¿~ÝÅÅ%;;;((èÆNNNÜ8z2þ¤êõŇJ!—�˜Éÿþ÷¿üüük×®Ñ.Är½òÊ+©©©÷ï߯þCHY¸páüùóë­4c4MAAAõsLqq±‘7^kkëªBL¥9¦ŽÓo>>>GeY¶W¯^·nÝÒýÃ0ñññ}úôÉËË#„øùù-[¶ŒòñÇs¤†Ù¸qã˜1cD"Ã0±±±^^^;wþí·ß¼¼¼^|ñE…B¡ðÊ•+ýúõ“Ë夲\bgg·jÕªqãÆq‡É*Í% „3fpGÁÁÁ?üðCãÆßxãÛ·oëÖóþûﻹ¹-X° 22òÁƒk֬ю£·!ãOª.¯-Ôr €™ôéÓçÖ­[wîÜ¡]ˆåêÝ»wFFFFFFõèÑ£ï¿ÿþ§Ÿ~ºxñ¢vZ6¤R©ŒäÓcJJJŒŒ&‹œœ* 1ÞÞÞÿ÷ÿgä±gÏž}çw¸&‘:tøé§Ÿ:vì¨ý)Ã0†aí],—––²,kooÏ}yŠa˜ŠŠ ±X¬·¾Þ###—-[VXXÈýˆT–K6mÚ´råJ¥R™œœìääÄ­À²¬•••6—”——³,ëàà T*¹z!Ü€Úa¹z®\¹ò /\¿~= àðáÃÁÁÁÚ-êmÈø“óÃë`&mÛ¶=|ø°\.www§]‹%R*•§NzñÅkú@›3f¼÷Þ{<ððð¨ÚL‹KNNNÕ\¿¢¢¢š“1wïÞÍÏÏ/++ãj<—ìÞ½;55U{úËîÝ»us !DïÌŸ¤¤$Bˆn÷�Ýý·v}½FEE?~\©T9…eܸq£GîÝ»÷ÁƒGŽéààššš™™©»ŽÞÖýýý£¢¢^yåÝ3‘¹zBBBBCCܾ}ûàà`#zæ“scÀ,>L™9s&íB,ÔªU«!6l ]ï©Õꬬ¬ëׯ_¼xÑøšÜA–e=¤ûSíB{#..ÎÅÅÅÅÅ%>>^ïG•®¯½1iÒ$‰D2yòdÃé>œ–““òì‚ $É”)St2vìX{{û_ý•[rìØ1???Ý}™î°ñññ„„„êt7düIùá8€ùtïÞýï¿ÿNMMmÛ¶-íZ,Kff¦¿¿óæÍÓÓÓqP*…/ú6Âù>€åÛ°aƒH$<xpaa!íZ,HyyùàÁƒ•JåÆJ�8ä�ó ؽ{÷½{÷:tè““C»‹PTTÔ½{÷ÔÔÔµk×öèуv9`¹0YÒ@ —�˜ÕÀwíÚuçÎ;wÒ.‡²´´´   ÔÔÔU«V^Å� ä�s6lصkך7o>bĈ1cÆ<|øvE¿ûî»AAAeee§OŸæÎˆ�@. ÀÏÏïÚµk&Lغu«··÷¼yóŠŠŠhe&åååÑÑÑ>>>ëÖ­ëׯß7:uêD»(�°8½€¦7nŒ3æôéÓ2™ì½÷ÞûðÃ|u“ÜÜÜ5kÖ,_¾<;;; `ñâѦ]�Xä�úV¯^ýå—_Êår‘H4hРqãÆ 6L0MkY–ß¹sçŽ;=zäääôé§Ÿ~ôÑG‚y‚�`BÈ%�–b×®]»wïÞ¹s§J¥’H$o½õÖÀûõëÇÓKOj4š£GÆÆÆÆÄÄ[YY 0`ôèÑ£F²äþº�@r €eQ(;vìØºukJJ ˲ööö/¼ðB¿~ýºtéÒ­[7ÚÕ=Û™3g.\¸pàÀäææB&Nœ8zôh^\$�èB.°P¹¹¹;vìøóÏ?ãââÔj5!D"‘ 6,44´K—.;wvpp ]#!„”””¤¦¦ž>}úܹs»wï.--%„XYY 8°wïÞ£GnÞ¼9í€7K�,F£‰‹‹KMM=vìØ‰'´]ÙZ¶lÙ¶m[ooï:´mÛÖÃÃà çÌfggß½{÷êÕ«iiiwïÞ=yòäÍ›7¹·›Î;÷ìÙ³K—.C‡åéá'�  ¹€O4Í¥K—Μ9“žž~âĉ3gÎhc !„a˜   WWWww÷-Z8999;;;;;Ë“J¥‰D*•ŠS?¦T*•JeYYYQQQaa!רV¡PdgggeeÉåòû÷ï_»vë&ϱµµmß¾}Û¶mzõêÕ±cG\E�ê¹€ßîß¿Ÿ––výúõ;wîdddܹs'33óÞ½{&üÓfÆÝÝÝÓÓÓÃÃÃÛÛ»U«V¾¾¾žžž8ƒ�L ¹@˜ ENNŽB¡ÈÍÍÍÏÏ/,,,***++ã&EÔjµF£Q«ÕVVVÜĉ­­­T*mÔ¨‘ƒƒƒ££££££³³³«««‹‹ íg� r ���X \×���,r �BH~~~zzºR©¤]�4hÈ%�@!;wî HMM¥]�4hÈ%�@!܀ѳ�èÂ{�ò8—à$�@r �Bw©{Ì—��]x�B0_�–¹�Á| �X¼�!8ï�,Þƒ�€Çó%8ŽfP¯m•ê2¸å÷{²ü ëȀ̗@½ÑÛ•¢ù ‡÷ � ó%PoX–岈öF4„ãÚ+€\�„`¾Ì+""B*•~ùå—ÜÝäädOOϦM›þöÛoº«q»d†a¸ûöísuuuuuMLLÔ®0~üx™L¶k×.½M莙››ëä䔓“CÉÎÎvrrÊÍÍ­j£zèÏ0ÌÔ©Smll*­'55µC‡"‘H& ·²páBí zw Ð}ªÿÒB¶mÛÖ¸qãððp#Å0 £7 ½ò*aêÔ© ÃTçÖ}õªÄ�°ì‚ !wîÜ¡]“îššêèèÈ- JNN>}ú´···‘úúú&$$$$$øùùiÊ- Ô[_oÌwß}722’eÙùóçOš4©Òî+ãÆ*•ªÒzBCC£££•J¥ví4jÔèçŸV«Õ•Þ5áKççç—˜˜Èe¦ªV6P^y•ŽÀ½ Õ|…µ¯^•Ï×ÈÏ� á˜7o!äÞ½{´ aÒÛ¹j4Ý…"‘ˆ›c`ÆÈE"Qyy¹R©‹ÅÚŸrKlmmõÖ×óòåËÍš5ËÍÍuqq¹råJ¥­4—Ž_QQQU=b±¸¤¤DwíüòË/]»v U(†wMøÒÙØØpåYÙp@=zåU:÷‚TóÖ¾zUÁœ-�‚ëªyé¶ð÷÷U©TÜï¡.¹\ÎÝöññIJJJNNöööÖ®`¸¤Ò1CBBBCCܾ}ûàà`ãÕe8¾X,®ªžàààuëÖ=zôÈÈS7n\JJŠL&;xð á]Cº¯�©ÉKçååÅ•g|eãç¯è•WéÜ RÍWXûêUÉxl€bΜ9„¬¬,Ú…€0‘§?ôëÝ8v옟Ÿ_¥{¥©S§J¥Rny\\œ‹‹‹‹‹K||¼v„±cÇÚÛÛÿúë¯Ï3>>ž’PÕ †[72~¥õœ={644”ÛÓÙ !$,,,''§Ò»F^½t›7o¶··=z´v:ÇÈS®*è•güE«Å+lˆÑn�²Ù³gGEEegg»¸¸Ð® º¸üß [Œ3gÎõë×M8f½ÂõK�€|OÀ2˜6”0 coo¿víÚê¯_ÅTr �‚ï ?Õ÷Ž“ï‡jZ¿%<_¼�!˜/�Ë€\�„`¾�,Þƒ�€Ì—€YùJêW_}eccSëk®7´‹µëâ×sfµÈ%�@æK€¶ï¾ûîŸþaYÖT{Y~í­ë wM³&Mš¬X±¢Fª¿’ž ïA�@®«´)Š–-[Ózi §pZ–e80wîÜ=¤ÒåæÉ+È%�@Èãã8˜/ú°k×.™L6aÂí½ŽnÚîtDgçgØRΰœáÈZFÆ!„<|ø000‹ã*•Êßß?))‰[Y*•r³ îîîr¹ü¯¿þb&666;;ÛÝÝ<«Óž‘FwÕlhØÜ®– ðcYÖÁÁ¡ª¡ ÛûUÚSP¯ƒ ñ’jô?UI¹��áááVVV´«�a HHHØ»w¯v§c¤gžîgö¨3YËÈ8œððð}ûö±,»víÚnݺi—_¾|ÙÍÍeÙAƒ9rdøðá³gÏn×®ÝéÓ§È>«ÓžñFwµkng|#»rnGïã㓚šZÕP†íý´7ôž‹î†Œ—T£ÿ)ýšÿ�ˆqãÆi/V `ZÕl gxã™=ê GÖ22çôéÓC† Q*•žžž±±±,ËΟ?_&“‘Ç]ŒŒ\¸p¡¯¯¯J¥jݺõ˜1cæÏŸÏ>«ÓžñFwµkng|ã¹D­VÏ™3gË–-Õ µ7ôž‹î†Œ—T£ÿ)=˜³�BÑh48ˆõÄÛÛ;))éÀÚ%Õì™÷Ìu†#WgNçÎ Åܹs† B‰ŠŠ:tèÐñãǹ½l§N/^<~üx‘H4qâÄ-[¶tìØ‘<«ÓžñFwµknWËx„B¬¬¬"##—,Y’——WéP†íýªz.º—Tëÿ)Bp�X–eÙÿû¿ÿ“J¥´«�aÚ¾}»½½ý¸qã´;ê43¼aø(ѵŒŒ£CÙ¼y3wwÒ¤I‰dòäÉÜš™™™"‘(33S{ûîÝ»¬A+;Ãí£îªßÜ®:/—ñ'¨]²nݺ)S¦T:”a{?ÝuŸ‹nAã%ÕèJúö�!„Œ9rß¾}ÅÅÅ´ 0•JµdÉ’íÛ·Ÿ={ßD³œö~è�„¢V«ñÖ ŠT*íÔ©Óþýûëò›o îꮦíýêr �‚óK á©¨¨¨û < "z,êYàm�Á| �Xä� ó%�`ð6�„¢Ñh0_`fæïDc¸ÅÚÕP•#—��!„¨ÕjÌ—�u|l¶ÇÇš-Þ†�€Ì—�X¤ê‡3Ä#ôí�óÁ| Ô+Ý~x¤êÖw …Âüíô´N:•a˜š¶Ö3ü2‹Þ“5lh¤‰‘Vy•ŽÌ•ñ̦zÆÛæ?^&“íÚµ«ªv†•óÌ®Šµdü²k�Ð@ôîÝÛÇLJv dÚ~x¬ÑÖwTÚé±:mçj×ZÏÈ“%4±3Ò*¯Ò‘+íÞWÓ‡ lÕ¯?kp‘ÙgvU¬ä�`Y–íÙ³§¯¯/í*@˜ôúá±F[ßQi§Çê´«]k=#O–44ÒÄÎH«¼JG®´{_Mr?²µµ­ôõ×]S÷ö3»*Ör �°,ˆ……ùûûÓ®„I"‘œ={öøñãº;6•JÕ£GíÛ·®ß½{÷éÓ§·iÓ†Ûóé=<..ÎÞÞþ‹/¾`YvÑ¢E„íîÓȘz? Š×\Ñ­íÅ_ ëׯw×øÊÏ|²†7üýý¹F9Æë´±±áôYoMÂl‘’˜˜˜˜˜À-Ñ{ý+Ý„a †­ä�`Y–}î¹ç‚‚‚hW¤×}Vë;*íôtwØÕo­WÍ'«wÃx»ARE«<##³Ïjªg|‹cÇŽµ··ÿõ×_+}ý+Ý„a †­ôí�BéÖ­[IIÉåË—i ÚéÑEýõG� ס‹vzt™äõ¯ ä� ס‹vzt™äõ¯ ¼ �!¸®�Xä� ×U�Ë€·!� ÇqÀ\ÐMÆ’YÂÿÞ†�€œ÷ RwÖ°ä� ó%PŸ,vÿ]ÇÓcqvm}ÀÛ�‚ù¨7ué÷¦×l¯ÒÚžsUf¤!Ÿv½ íÛ·ÏÕÕÕÕÕ511Qw®QŸÞS#•uæ#„TÕÏä=«ó²hïAhêrQ6� ooï>}úЮ„Iw_CjÒï­ª&vº7t{ÎU:©º!Ÿv½ ùúúrÃúùùé Réó2|Róô ¬ÎË¢e¼¡%¤ú�€%ðôô|ñÅiW¤—Kªßï­Ò&vÜ „v4Ýžs•ŽFªnȧǰ«7¬X,Ö¤Òçeø¤8æéAX—EËxBKÈ%8Ž�„àü¨O666r¹\{Wïð„¿¿ll¬J¥âö¬ºÆ—’’"“É<HqppHMMÝ·oŸî:IIIÉÉÉÞÞÞFF‹Å„ÐÐÐÁƒ·oß>88ØÈ†|||ô†ÕR•J¹tîÜY¡PÌ;×ÁÁaÈ!„¨¨¨C‡?~œ :uZ¼xñøñãE"Ñĉ·lÙÒ±cGÃzêþ²hy},í`�ÁÍÍmÀ€´«�aªu¿7n¡¶‰Ý‚ $É”)StÑë9W£†|ºëèn(..ÎÅÅÅÅÅ%>>ÞpÝòªº¡e†„ÕyYŒ¼ÚäéÙ,ÃÍ™úö�!„¸ººvéÒ%!!v!�5ÀŒ¨ê§gÏžõóó㎛PA«žñ—ÅÂYÒÔ �ЃëЃÀ¨Õêððð»wïæææÒúÝFÂZ@.�Bpzà'#;éuëÖ]¾|yÉ’%7­„¼Î.<žê�rttìÛ·¯á$�ø¨°°ÐÏϯqãÆW®\±µµ¥]Ô�æK�€\W „嫯¾ÊÎÎ^µjB ï`Ú�Á÷„A@nß¾½|ùòž={¾þúë´kÃÛ�‚ù9sæ<zô(::šv!PÈ%�@æK@(RRRvîÜ9vìØÎ;Ó®joC�@æK@X–6mšT*]´híZ –K�€Ì—€ lÛ¶íÔ©S3fÌððð ] ÔÞ†�€p20_¼VVVöÉ'Ÿ¸»»Ïš5‹v-P{øž0�µZMÁ| ðZttôÝ»w7lØ`ggG»¨=¼ �æK€÷²²²¾ýöÛŽ;¾ùæ›´k:A.�Ì—�ïÍ›7¯¨¨héÒ¥ø5æ;üÿÀó%xCžºpᆠ^}õÕÞ½{Ó®ê oC�ðß| Žã�OMŸ>]$EEEÑ.L�¹�0_<–””4eÊ???Úµ€ àm�0_|UQQ1sæL''§yóæÑ®Lß�Ì—�_­Y³æúõëË—/oÒ¤ íZÀ4ð6�˜/^ÊËË[¸pa@@ÀäÉ“i×&ƒù�À| ðÒ_|ñðáà 6X[[Ó®LoC�€ëªÿüóÏ??üðCß¾}L»0%ä�ÀuÕ€fÍš¥V«—.]J»01¼ �æK€gŽ9²gÏžðððvíÚÑ®L ¹�0_|¢Ñh¦M›fooÿÅ_ЮLoC�€ó^O6mÚtîܹ9s渹¹Ñ®LoC�€ï o”””Ì;·eË–Ó¦M£] Ô |O�0_¼±xñâÌÌÌÍ›7K¥RÚµ@½ÀÛ�`¾ø!33sÉ’%]»v=z4íZ ¾ —��æK€>ýôÓÒÒÒèèh†ah×õ…aYÖ ›¹víÚÛ{üˤû[e¸°š?5É Ø�˲=‰Db1Ží‚…:{öl×®]_ýõ;vЮê‘9r ˲øfɨ#lB`› ^�6Á—j4ÈæÍ›årù¤I“ùû,,võQ@›6mBCCI ™)—,Y²D÷nU7êòS“ ‚M£�lÂr6A½€†° �Ë4þü… ÖôQf:Ž�5•œœü÷ßGDDØÙÙÑ®,_ÒU­ ¨¨¨xþù狊ŠRRR7nlÉÏ›Ðý©O«V­H áX2€…Ú¿ÿâÅ‹ßyçä0®ÒYô:ºÿ¾H$jÖ¬™IF«£èèèÛ·o¯^½ÚÏÏv-PïpÚ‡0±,[TTTQQA»¨=î¿'¢#GŽ £]!„(Š/¾ø"$$äí·ß¦] ˜r‰0) ™LöÙgŸÑ.jË%ÖÖÖ´ †¨¢¢ÂB~÷.\˜ŸŸ¿dÉdô¹D˜°K�ü'E’K®_¿þã?¾üòË/¿ü2íZÀLK„ »4¨¨¨`Ÿ É%3fÌ`ŸþF'r‰0©T*‚Sx®¢¢B,›ê4F€±„\rðàÁ}ûö½ýöÛ!!!t+sB.&Ì—€%ì Á¢þë§V«§OŸîààP‹ `�¯áó´0!—@w ƒ«™RC{=U*Ý7õë×_¼xñÛo¿µï*ƒÙ —r‰�Ô(—èî1ó´¡í³ºó%EEEóçÏ÷ññùðÃiÕ�´ —r‰�ÔhÇÀÅZù a†a§1îô&Z[ÿæ›o²²²Ï°P)�� �IDATvìØakkK« ç—wÞ+r ¯Õ}"=""B*•~ùå—ÜÝäädOOϦM›þöÛozk.\¸ÐÅÅE;éb¸¦Þ zwµ7öíÛçêêêêꚘ˜¨ý‘^5Ý4Ã0S§NeÆÉÉ)''‡’íää”››[ÕÊ666•n˰àgn}×®]2™l„ •Å0 wÃð‰óÅù’;wî|÷ÝwaaaǧR�PÆ‚:tˆ²qãFÚ…@íõêÕ«U«V5zˆî_4!$>>>55ÕÑÑ‘[”œœ|úôiooo½6jÔèçŸV«ÕU­©·‚Þ]ív}}}üüüª*£¦›æ~“U*Õ»ï¾ɲìüùó'Mšd|eã¯öÆ3·°wï^ÃwKÝ%†Oœïìííßxã *›5jÃ0§N¢²u ¹D˜þüóOBÈÖ­[iµ×½{÷€€€=D/—h4Ý…"‘H$qñõøË/¿tíÚ544T¡PTº¦Þ zwu7Q^^®T*ÅbqUeÔtÓ„ŠŠ –e/_¾Ü¬Y³ÜÜ\—+W®_ÙÈë£Ñh´Å<së666Ü32žK Ÿ8ßÙÚÚŽ=ÚüÛ=qâÃ0cÆŒ1ÿ¦ÁBà8Ž0áü¨ûDºÞɰþþþ±±±*•ŠÛ1ë7n\JJŠL&;xð`¥kê­ wWËÇÇ')))99ÙÛÛ»ª2jºiòøJ<!!!¡¡¡ƒnß¾}pp°ñ•+åààššºoß¾êoÝÛÛ;))éÀ†£ÙØØÈår#Oœ×¨ÇaYvÚ´i‰ä«¯¾2ó¦Á‚ÐFP/bcc !±±±´ Úkß¾}‡jôòô|‰ÞcÇŽiÛ±>–““Séšz+ÞåV‹‹‹sqqqqq‰¯ªŒZlZ»r||<!$!!¡ªgTé+ µ`Á‰D2eÊ”ªž—á€Û·o···7nœáhS§N•J¥ÜrÃ'ÎkÜ jo¿ý¶™·»}ûvBÈܹsͼ]°(B>Ÿ¼!ûí·ß†¾oß¾W^y…v-PKmÚ´±³³;uêíBøJØß—©WJ¥R*•Nž<yÕªUæÜhPPPyyyzzº½½½Ù¶ –ß&î8®CÏkÔ/¸YÌy„’Z£r xÙ²e111% ö[„óK@¹YÌÿòàÁƒ¯¿þº]»váááfÛ(X&œ÷*LÈ% È\¼`þ EFF.]ºT$™m£`™K„ ¹D�K€3¾|ùrLLÌàÁƒûöíkž-‚%C.&䍯iÆ¿²k™¾úê+›J+7ÕÓ©Å8¦}%-íÿÅÌo Ó§O·²²Z¼x±y6¹D˜¸iXœ÷Êk&¿~É3×ѽ¶zU´+8;;ÇÄÄÔ¥¼júî»ïþùçsž˜bi)ÁüÌ™KÿüóÏÉ“'˜as`ùK„ ó%P÷ÆiµÛ—s— O_®ƒ<}Á–efÍše|(ã;øjîþ EË–-«Uº‰àä\³½¨Tª™3g6iÒdþüùõ½-à äaB.€ZÌ—0 #•JW¬X¡½Ëݨªù\^7V· ž^g;½òô~ZUOA½¡ôž—¡ÔÔÔ:p×’ç–vÔ«ªÇÞO?ý©;¾‘N‡„ñãÇËd²]»véV«ûú׺) uf{Y»víÕ«WçÍ›çääTßÛÞ0ÓõÛÀ¼,X@ÉÈÈ ]Ô·ËŸ8qbMxùòe777î¶öÜxó¹JßHó%Ú‡4iÒdÍš5z£UÕÏÏxy¬Ñž‚Ä` Çð†Vhhhtt´R©Ô.1ì¨WisÁ 6Ì™3GoXãUqƒVõëÒ®Ó§OB~øá‡zÝJ^^ž‹‹‹ŸŸ_yyy½nøÅ²þÀTæÎKÉÌ̤]ÔRyy9!„ëš[MóçÏ—ÉdäñuNYýk5›ÏU?—TUCUýüŒ—ÇVÑ<>¤¢»¾n×=ÃJÄbqII‰îÃŽz•6ôóó+((ÐÖH§CB7ˆ­­mUO°.MéJII!„¬]»¶^·2cÆ BÈž={êu+À;8Ž#Læ¿ü�˜V-&Ò£¢¢:tüøqÖ`ÄHó9ÓÒkƒ§ÛÙΰ<ÝŸ6ÌãÞ¡t7ìºg(88xݺu=Ò.1ì¨Wi½U«V½ùæ›jµZw4# !zƒ>Áº4¤Ë ÇqnݺµbÅŠÞ½{¿úê«õ·à%Š™êÏ´iÓ!¹¹¹´ ZÊËË#„|üñÇÕȤI“$ÉäÉ“‰Át‚‘æsĤó%ܻж žng;Ãòtj¼§ w£Ò®{z+Ÿ={644”;¥ƒ[bØQ¯ªæ‚111ºÃ¯jìØ±ööö¿þú+·¤ÒןԶ) ]\Ú¼ysýmbøðáVVVgÏž­¿M�O¡¯•0M:uÅŠEEEè4ÁS999Íš5›5kÖ·ß~K»hpþøã—_~ù×_1bD}ŒôèÑçŸ><<|Æ õ1>ðŽã¾ÃwøŠL{½W½O¿fúôévvv‹-2Éø 0È%„½ßá(2í¯ßòåËuïnÙ²åôéÓ³fÍrww7Éø 0È%¤R©D"‘•þù g.E¦Í%K–,ÑžÛ[ZZúé§Ÿzxxp_Æ0„ë” SÝ/ t™¹q€.Óæ’ÌÌÌþýûççç;88,]ºôßÿݸqc£FL28>O ZÑòÙŽã  2ᯟöä’?þX.—GEEuîÜyìØ±u„ ŸÆ„ ¹„ïÌ~ w±/s>,– ýJJJ¸6lø÷ß‹‹‹£££qˆŒ@.&ä¾3.©Q¶ÐÍ"%ÂcÂ_¿ââbííxzznÙ²eïÞ½ Ç›èBh&侫ݎÁ°oŸ^o9Ã%ºån¶¾#F[îéÇ0LDD„T*ýòË/¹%z­ìÀ2™0—éÞ½wïÞ?þ¸téÒ ¬\¹ÒÏÏïT ¹D˜T*þÚy­v;–eÏœ9óõ×_k—Œ1bÛ¶móæÍ3²DOxxø›o¾YZZª;¢;2ûtÏ­>úhýúõëׯÿ裴 _zé¥'N,]º”»µdɽ˽ƒ¥©¿\¢5iÒ¤ .ôîÝ»î›�ÁqaÂ÷qø®;†ÈÈÈeË–êÎFôë×eÙÛ·oY¢çêÕ«“&M²µµ5>²¡Û·o>pà@†aòóó¹»kÖ¬Y¹retttrr2ZÛ[,~M]÷8ŽÖüÑ¿ÿº‚„ùaÂq¾3Uß>Ãu†Kô¶¾3ÞrO«Ò~xzQF¯•X¦ú›/™0aB~~>B Ô„\ÂwµØ1Œ?>,,l„ º ·nÝûÓO?Y¢gÆ &Lж ¬tä÷Þ{Ï××·¬¬L7EGG?ž²~ýúªçbJXXXß¾}«ÿÔÀÌLxùÝ\?hРº †/ø S»ví¬­­Ïœ9C»¨¥sçέZµ*""¢]»vµÄð¼øN/TÇ'Ÿ|òÍ7ßdee¹ººÖq¨˜˜˜wÞygôèÑ+V¬hÚ´©IÊaÃ|‰0©T*\N‘×:vìC» h †±±±1Éœ«D"Ù³gÏ«¯¾Z÷¡ À‡'aò÷÷wuu=zô(íB ºŠŠŠ”JeqqqYYYEE…J¥R«Õ,ËŠD"®Õ‘D"±µµuqq¡],�@}Á|‰¨TªÒÒR¥RYRR¢ÑhÔjuiié£GÒÓÓÅb±µµµD"‘J¥5Âei)//OKKËÈÈÈÎξuëÖýû÷óòò233 EIIINNNFkÔ¨QãÆ›5kæììÜ´iSOOOwwwWWW___ooo777\ �x ó%< V«ÓÓÓÓÒÒrrrärù;wòòò EVVVIIIAAAiii5‡jܸ±L&kÔ¨Q‹-œe2Y«V­ÜÝÝ›6mÒªU+“ÈËË;þü¥K—®^½zíÚµ´´´è­ãäääæææää$“ɸ¥R©T*µ¶¶‹ÅÜ4 7q¢ÑhJJJ”Jeyyy^^^aaaqqqVV–B¡ÈÎÎ.++ÓY,‡„„tìØÑËË«mÛ¶:uòòò2ã³�¨=ä‹SXXxîܹK—.ݺuëüùóçÏŸ×^ûÃ0Œƒƒƒ³³³›››L&kÚ´©­­­D"±···²²²²²‹Å,˪Õj•JUQQÁ P*•……… …¢¸¸X¡PÈårÝï‚B¬¬¬Z¶lЦMÿÐÐÐvíÚI¥Ró¾�¼¤ÑhΟ?Ÿ˜˜xùòå3gÎܼy“[Î0 ÷’úúú¶jÕÊÛÛÛÝÝÝËËË´Syyy÷ïßÏÉɹ~ýúÕ«WåryzzúÕ«W¹«PBlmm{ôèѹsç^½zõéÓG"‘˜jÓÀG*•êþýû …¢°°077·°°°´´T|Õj5…µÇ5j$‘H$‰ƒƒƒL&“ÉdÎá“ ˜r }æÌ™3IIIçÏŸ?}ú´î5©<<<<==BBB¸OØ^^^¦z/P«Õ·nÝÊÈÈÈÊÊÊÈÈøçŸnݺ•žžžÍ­À0LPPP—.]Ú´i3`À€àà` ÐUVV¶cÇŽ={ö$%%q׋Å;vìÝ»·ŸŸ_hhhûöímll¨ÔƲì?ÿüséÒ¥K—.ýý÷ßGŽá:¨‰D¢Ž;öë×ïùçŸïß¿?þCìÑ£G©©©7oÞ¼yófFF7Û*—Ë L2>Ã0®®®îîînnn>>>>>>mÚ´ D^ZC.¡æäÉ“'OžüóÏ?ÿúë/n‡!‹;uêÔ½{÷ààà¶mÛ¶mÛ–Öwj ¸ÃéééG޹|ù²F£!„4mÚ´oß¾ýû÷ùå—=<<¨Ôf ²³³¿ûî»ÄÄÄ‹/BÄbñ믿ޡC‡ž={véÒÅb¯“••µÿþcÇŽmß¾û•“H$áááC† éß¿¿H$¢] Ô Ë²×®];zôhZZÚÅ‹¯\¹’••¥»B‹-Z´háîîÞ¬Y3WWWgggGGGGGG;;;nRÄÖÖVô˜ö"wúšR©,(((,,,,,ÌÉÉQ(¹¹¹÷îÝ“Ëå …âþýûºÛòôôìÚµk×®]ƒ‚‚úö틯Bõ!—˜Û¹sçvîܹvíÚÜÜ\BˆX,:tèsÏ=׳gÏŽ;Zæ.­´´ôÔ©SG={ölBB—Q:uê4xðàˆˆˆ†sM‚’’’Í›7ÿòË/)))„77·#F¼üòËýû÷çݧãGþý÷ßqqqÇW«Õ...cÇŽˆˆðññ¡]Ô€F£9xðàÉ“';vòäIíEÌ\]]»uëæååàíí]ßg©Tª+W®Ü¿ÿüùó.\¸yóæ¹sç´|||¸w¹çŸ¾þÊ�@.1“¼¼¼uëÖ­_¿>--8tèÐ=z¼òÊ+üÚ¥©Õ길¸ìرãáÇ„>}úŒ5jìØ±>åÞ½{ÑÑÑëÖ­+))±±±?~üÛo¿ÝµkWÚu™@^^Þ¦M›8@éׯßìÙ³q1V ———·}ûö£Gîܹ“;‹ÈÆÆæå—_îܹs—.]:vìØ¬Y3Ú5BÈÕ«WÏŸ?æÌ™«W¯8p€ûHcgg7zôè0€ÖQN°h,Ô³+W®¼ùæ›ÜŸŸ··÷ܹsoݺE»(Ðh4ÇŸ2eг³3!¤qãÆÓ¦M»wïíºLL.—¿÷Þ{ܹ{ôè±råJ•JE»¨zqÿþýéÓ§s3v!!!GŽ¡]è{ðàÁòåË;tèÀ½{ÛÙÙ <xýúõ—.]¢]Ú³©TªÄÄĹsçvíÚ•û0Ö¨Q£#FìÙ³§¼¼œvu`AKêÑÕ«W‡ Æ0 Ã0'NÜ¿¿F£¡]”éUTTlݺuÔ¨Q„kkë÷Þ{/33“vQ& Ñh~øánhÀ€§N¢]‘9(•ʨ¨(î ;¯¾úê;whW,˲»wï~íµ×¸s€$É;ï¼óûï¿WTTЮ«– ~úé§‘#GrE&“͘1ãæÍ›´ë‹€\R/òóó#""¸¯ØÍž=;??ŸvEæpâĉB¤Ré?üÀëöÏ?ÿøûûBüýýSRRh—cnÙÙÙï¼ó÷Ñ;wÒ.§áâ±››!D,¿ñÆ[·nå., J¥rõêÕ:u"„XYY}ðÁYYY´‹ÊKLïØ±c\³«nݺ¥¥¥Ñ.ÇÜRRRüüü¸=:OŸþ¡C‡ìíímll¾úê+¡µ©ŽS§Nq§Á.X°€×)“§V­ZåääDiÚ´iddäƒhWTÎ;7jÔ(±XÌ0Ì;ï¼£P(hWÔ —˜ØêÕ«E"‘££ão¿ýF»šV­ZeccÓ¨Q£?þøƒv-5³ÿ~kkk77·Ó§OÓ®…¾¢¢"®1ýÈ‘#MÌ&//ïå—_æITTTii)íŠÌäÎ;#FŒ „ˆD¢O>ùDH3CP}È%¦ôÉ'ŸB:tèðï¿ÿÒ®…¾óçÏ{xxˆD"E´³gÏÚÚÚzyyݽ{—v-–B­V3†òÑGÑ®¥Aˆ‹‹³µµ%„L˜0¡°°v9¤¥¥qGvºtéòðáCÚ倹ÕW.áï7}j]ù?ü@éÓ§OII‰iKâ/¹\îïï/‹>L»–g+--õõõuppƦLH­V¿øâ‹„ýû÷Ó®EàV¬XÁ0Œ‡‡ÇåË—i×B“Z­ž={6Ã0R©ôÌ™3´Ë³ª¯ë—0ŒY¯ŒbÂÍÕn¨«W¯vèÐÁßßÿÔ©S¸²¡®ÌÌÌ:ˆÅâ«W¯:::Ò.ǘèèèéÓ§ÇÄļõÖ[´k±8yyy­[·öðð¸pá.]_OV¯^ýþûïwéÒåàÁƒ2™Œv9ô%%%½òÊ+ Ü<y²}ûö´Ë3áÓ½Œ¨*I˜í tΜ9,ËîÙ³¡DO‹-~üñÇû÷ïGEEÑ®åbbb<=='L˜@»KÔ¤I“ˆˆ®ÕíZ„éàÁƒS¦LéÖ­ÛÑ£GJ8}ûö=~ü8˲}úôá®â U`` w >•Jåï”DáfÏV¬XAqww—ËåýõÃ0±±±ÙÙÙîîî„… º¸¸<sÇ¿oß>WWWWW×ÄÄDnɶmÛ7nnä± ÃL:•»Yrr²§§gÓ¦Mûí·ªFÐÞЭJû/wÃpÝ­ìÚµK&“ÕnŸ$—ËãããGåëë[‹‡ Þ°aÃÚ´i³víZsN¡ÕTnnîµk׆ʯËïšÓСC !G¥]ˆ�1ÂÍÍ-))‰;¹8;wŽÍÏÏŸ9s&íZÀ\ÂÃÃ÷íÛDzìÚµk»uë¦=Àsùòe777–e täÈ‘áÇϞ=»]»v§OŸ8p ˲5úù矫:_š<>KÃ××7!!!!!ÁÏÏ[âçç—˜˜ÈÅ”ª/B6nÜÈ}E3(((99ùôéÓÞÞÞU ½¡W•î& ÇÑÝJ@@@BBÂÞ½{TU•mÛ¶BbcckúÀ†ã‹/¾ „Xò!ó+W®B¾ýö[Ú…X.®Ë4^¢ú°dÉBȶmÛhb¡† &‰p6zANŸ>=dÈ¥RéééÉíYçÏŸÏÍ"rgZDFF.\¸Ð××W¥RµnÝz̘1óçÏgYö—_~éÚµkhhh¥_4×îÝE"Qyy¹R©‹ÅÜn‰ñ\¢½”!×Ù’›ö¨jí ½ªt7a8ŽîVªSUU¾ûî;BHjjjMØplÚ´‰bÉ(ËÌÌ$„Ìœ9“v!–ëêÕ«„E‹Ñ.D€ºvíêîîŽobW寿þ"„,Y²„v!`V;wV(sçÎupp2d!$**êСCÜQ=BH§N/^<~üx‘H4qâÄ-[¶tìØ‘2nܸ””™LvðàA#ó1>>>IIIÉÉÉÞÞÞÜ///n‰ñ‰®# !Äßß?66V¥RqÇ›Œ W•\.¯jÝ­x{{'%%q­ËjŠ‹qyyyµxlÁ5O殢m™ÜÝÝ=<<hb¹þüóOBˆ0ºZ–eÏŸ?ß³gOœP\•=zX[[Ÿ?žv!`,ËÆÄÄB6oÞÌE•I“&I$’É“'s?ÍÌ̉D\Çî67™Æ=<,,,''Ç0ïdzqqq......ñññÜ’Í›7ÛÛÛ=Z;ƒB ¦(t—;vŒ»~¨v¡‘ôªš:u*×ߤÒqt·²}ûv{{ûqãÆóL.\ „|úé§5}`Ã1dȉDbá—‡â.?“˜˜H»KôèÑ£–-[zzz>zôˆv-BSQQÁ0ÌÛo¿M»‹&“ɦL™B» 0RQQñõ×_·k×ÎÌ×ÛÞ³gO@@ÀEÔê’!º#Ð¥ÑhBBBœ-|¿KËÕ«W†5jíBž!''ÇÑѱeË– óbVÆEDDBbbbh"L®®®½zõ¢]…åR(„ˆˆÚ…€9±XÜ­[·û÷ï×iƒ9˜g®ooo¿uëÖºl±Ž#˜ÖîÝ» !¯¾ú*íB,NEEEÇŽ­­­yÑ+ç÷ßg¦K—.ˆ˜º¸¯æq'¼C}=z´µµµ\.§]ˆ…úþûï ¾[Ð`ðõª¬è7Þ „,\¸v!D­V<˜òÍ7ßЮ¥º~üñGBHûöí³³³i×BŸF£ùðà !]ºtÁœúsüøqBHxx8íB,Q~~¾›››‡‡‡ök lÈ%&SQQÑ£GBÈ”)SÐnŠeÙÒÒÒ—^z‰2zôhÚµÔLLLŒ••U³fÍŽ9B»š<xлwoBHŸ>}”J%írnäÈ‘ Ãà«Âz´ŸmxÔf ê¹Ä”ÊËËû÷ïOéÑ£GVVírhJKK  „Ìœ9“ß~<xð`ãÆ !¯¿þzrò‘J¥Z±b…££#Ã0Ÿ}ör¶äææúûûÛØØ$$$ЮÅR¨Tªÿû¿ÿã>ìÑ®ÌÇsINƒ­Ý9³õG£Ñ|úé§ Ã888,[¶ÌÌg[‚âââY³fY[[[[[oܸ‘v9µWZZúñÇB¤Ré¬Y³*½N íÞ½»U«V„Ì™YFF†———H$ZµjíZèËËËëÙ³'!døðá8‚Ó XÖNcükÃÕÿQ-6d*ÇŽsvv&„´nݺᜫUVV¶|ùrBH¯^½„±#?~üxëÖ­ !¶¶¶ï¿ÿþÕ«WiWT_***Ö­[çææFiܸñ²eË0Mb~r¹¼]»v„nݺýûï¿´Ë¡æÐ¡CÍš5#„̘1£~ºkàø‘KLµr½¢G­V/^¼ØÞÞžâáá±aÃÿu•——ÿý÷Mš4!„8;;¯^½švE&¶{÷î¾}ûr_7ëÙ³çâÅ‹ËÊÊheæÐ¡CS§Nµ¶¶æþû~øá|<¥¨¬¬lÚ´iVVV‰¤ι޼ysøðᄦM›âVÃô_'Þ7ß|³qãÆ;wîüo)!ÖÖÖ,Ë&$$4kÖ¬Y³f\–eÏ;×¾}{®½·$))ÉÃãI“&»víâ–,X°€›0¨ô.ÇÍÍ-33óÈ‘#„={ö<xð€ëÈCùàƒ$É_|¡­§ªM®üÌÁµO4"®Îs©‘ŠŠŠåË—s;l[[Û™3g=z”ç[TJ¥R%$$|ðÁÜ…\[´h#àÙ—.]zÿý÷¹óN¬¬¬^z饘˜˜J¯+hùÊËËÿüóÏ)S¦´hÑ‚Â0Ì‹/¾¸wï^ÁüròÝ©S§BBB¸¹«¨¨¨òòrÚÕ»ÜÜÜ™3grÝB&L˜€/Ä5Xÿ혹Özÿ-ÕihgØx/444::Z÷ü|Öxzýó*mòWUG@BH|||jjª£££¶žª6m¸ò3×>µJ/üúÌçR f×®]}úôá®3íååõñÇ:tˆ§Ÿ„ÊÊÊâââFÅ}‹ů½öÚþýûi×e&J¥rÇŽC‡åÒÃ0:tX°`Abb¢…iE£Ñœ={véÒ¥Ô6­íÕ«×·ß~ÛÀOÓ¶L*•jãÆ\›>ø@8Ñh4û÷ï5j÷öøÊ+¯œ?žvQ@Ó¹„kYgkkûßÒ§Ûæé5Þ‹Å%%%º£¶ÄÓëŸWi“¿ª:B¸m†¹ÁpÓ†+?spíS«4—<ó¹ÔŽ{÷-Z¤í0Ò¨Q£aÆ­^½úòåËþ9U­VŸ:ujÙ²eýúõãâwDcåÊ•>¤]{÷î={vÓ¦MµSnmÚ´yë­·6mÚtêÔ)ê¹S£Ñ¤§§ïÚµköìÙ}ûöåfz¸©»ÁƒGGGЭžI¥RmÛ¶ëJÆw²jÕ*žÎÒé¹xñâœ9s<==¹|ÿúë¯_¹r…vQ@ß¹$11111±Ò Ãûúúr?õõõå–„††.[¶Lw^1(((>>^oFA¥RõèÑcûöí•ÞeY6..ÎÞÞž;þ²hÑ"íåü ã‚î|‰Þ¦+ÍÕó*k�� �IDAT\÷¶ ×�¨šÏ¥î>|¸hÑ¢þýûkŠÅâÞ½{GFFþþûï÷îÝ3Õ†jM£Ñܸq#>>~Ö¬Y=zôàŽB$Ék¯½¶dÉ’¢¢"Ú5Zôôô 6Œ9288X·ûZHHÈ Aƒ¦OŸ¾zõê?þø#--­þæTrssSRRbbb>ÿüó1cÆhxrllløÍ7ߤ¦¦Zx†J9sæí·ß¶±±á#öìÙ3::úâÅ‹´ëª•JuàÀíÁqBˆƒƒÃœ9sòóói—–‚aY–a˜±cÇÆÆÆþôÓO#FŒà¢+ûøÄ‹øøø·Þz‹²~ýúAƒBÎ;7a„K—.qCBŽ?>a„7nhÏØàÞšÃÂÂbccõîr#Ëåò–-[Þ½{×ÝÝ»}ûömOOOíÖ onÚpj®û?üpݺuÜ™ŒÏ|.ĤX–=qâÄÁƒ:tôèQµZÍ-çúxzzk'*L.'''##ãŸþ¹uëVzzú7þþûom1ÖÖÖ}úôéß¿¯^½:uê„®§Æ©Tªäääëׯ_¼xñúõëÜĉî NNNîîîNNNnnnÎÎÎ2™¬iÓ¦2™L*•ÚÛÛK$nÞÎÊʊ뀭V«KKKËÊÊ=z”››[XXXRR’••¥P(òóó322¸ïnh7Á0L×®][´hÚ±cÇÐÐP///³¿`zfÓ¦M‡ÞµkWqq1!ÄÍÍ­wïÞ={ö|î¹çÚ·oožæäÉ“<|øð‘#G¸Žî!!!£G8p ÷ý#�­ÿr‰î;P”–––ššzþüù‹/Þ½{÷Ê•+º?•Édîîî>>>ÎÎÎnnnvvv2™ÌÉÉÉÆÆF"‘ØÛÛ[YYq»4–eÕjµJ¥ª¨¨P*•ÅÅÅJ¥²°°P¡P+ ¹\ž——'—Ë322´„Â0L›6m|}}CCCÛ´iÓµk×–-[šý•”ܽ{7==ýöíÛÙÙÙ·oß–Ëå·nݪ㟞““““““‡‡‡»»»«««¯¯¯OóæÍCCC-pÿ¦uöìÙøøøƒ¦¤¤p¿Hb±øÿû_```·nÝ:wîܶm[Ý93³IOO¿sçÎ¥K—.\¸pöìYîÛõ\y/¾øâСC €  UA.±hæÄ‰Üž,===;;[.—ß½{—;K±ŽƒÛÙÙ988´jÕŠûìèáá€]šÙ?|ø°  @+**T*•Z­Öh4b±˜Ëš5’J¥¶¶¶ŽŽŽ2™¬qãÆ®®®´Ë‹ R©Ž;–ššú×_¥¤¤dggkäîîèåååííݲeK77·fÍšqת£üûï¿r¹üÁƒ7nÜÈÈÈxðàÁ±cÇtç}ƒ‚‚ºtéÒ¥K—=z„„„ཞ ‰„¯Š‹‹³²²Š‹‹ óòò¸s“KJJ¸™J¥bF$‰Åbkkk‰D"•J­­­¹£R©´uëÖxƒ�¤²²²“'O^¼x1--›¥»uë–Þ: ø¸¸8::6iÒD&“ÙÙÙÙÙÙI$[[[í1DµZͽŸ”––*•J¥RYPPPPPP\\œŸŸo8¦ŸŸ_pp°¿¿¿··w·nÝBCCµ§ÐTr �€À±,{ëÖ-n¶U.—+ î䤂‚ît¥ÒÒÒ’’’GU5‚T*•J¥²ÇœswwwwwwsskÕªUóæÍÍù¤@¨K��à?eeejµú믿þꫯ.]ºäãã#‰$ íº ©ñ ›™OFÁ¹/��f#•J !ÜÁ;;;ÚAƒCáTm��°d܉«ÜÌ ¹��ž‚\ý—K†‘J¥+V¬ÐÞˆˆJ¥_~ù%·d×®]2™l„ zç®Zö×_1 ›íîîÎ0uêTîÒ„•Ž?~üx™L¶k×.nÉÂ… ]\\Œ|Cdß¾}®®®®®®‰‰‰Ü’mÛ¶5nÜ8<<\û¨g��Ï„\4i¯üzùòe®ã.[Y3¼€€€„„„½{÷’§/÷^öx•ޝ×)°ªÞxÚͶôóóã.¯]§î ö��`Ú´i„ÜÜ\Ú…@Cİ,¹lÙ²ÂÂB†a¸+s7´½ë!¶¶¶\?‰DÂ꜈º`Á++«M›6]¿~= à¹çžkݺõÂ… †©¨¨àNžªt|®ÇƒƒƒR©$„lÚ´iåÊ•J¥299ÙÉÉI;¾¶�±X\ZZʲ¬½½}EEE¥%U5��TßG}´|ùò‚‚™LF»hp¬!QQQ‡:~ü8ût Ýõ¼½½“’’8 ÷øN:-^¼xüøñ"‘hâĉ[¶lÑö½Ô^N§Òñ“’’’““¹Þ„qãÆ¥¤¤Èd²ƒVZ¨ÞC¼¼¼¸%Úuž9��<Žã�EV„ñãLJ……mÞ¼ÙÈzŸþùˆ#vìØ¡·¼S§Neee'N$„„‡‡‹D"m.Ѫtü­[·Ž1âóÏ?çî2 #‹Y–íÛ·o¥DGG?~üøñß}÷·$22rĈ›7oÖ g��Ï„\ѹ:ˆ ¯J;gΜëׯ›d4��˜4iÒÚµk=zT=̪ÂïÎ ÃØÛÛ¯]»–v!��Âù ˆN.1Õd •É��aS«Õ ÃXYáW@~í��à)jµ“%@ r ��<¹(B.�€§ —�EÈ%��ðä ¹��ž‚\!—��ÀSK€"ä��x r P„\��OA.ŠK��à)È%@r ��<¹(B.�€§ —�EÈ%��ðä ¹��ž‚\!—��ÀSK€"ä��x r P„\��OA.ŠK��à)È%@r ��<¹(B.�€§ —�EÈ%��ðµZ-‹iW r ��<ó%@r ��<¹(B.�€§ —�EÈ%��ðä ¹��ž‚\!—��ÀSK€"ä��xŠJ¥B.ZK��à)˜/ŠK��à)È%@r ��<¹(B.�€§ —�EÈ%��ð˲¹hA.�€'Ôj5!¹hA.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x¹èB.�€'K€.ä��x‚Ë%b±˜v!Ð@!—��À˜/ºK��à ä  ¹��ž@.º–ei×���–B.—Ÿ?¾[·nNNN´k†¹Ä²üøãŸþ9Ã0„Æ€áÂj®V—ÇZòj–S žWuV«M�€ÀàŒkËâââÒ¶m[BkÀpaõWÓh4&Í„«.¤ò²Q Cµ[Ír*ÁóªÎjÕ|¬L& «ÿßôó%`YªŸi‚‚‚|}}÷îÝkÎ UÍÕ,§s>¯”””ýû÷Ož<ÙÅÅÅB nàÿ_µ~úõò·-P:t8wîí*ó%`Y´ŸHž¹¦H$²²²’Édõ_TKttôþýûßÿý6mÚЮê„VB2íjæ©ÄÁÁÁüÿA†\|%‰¸/�€iUÿã€Éá{ÂÀWVVV†v�”…‡‡9’v�&ƒùà+Ì—�B®_¿^\\L» �“Á| ðæK�!VVVè $È%ÀW"‘¹�¹ø h‚à —�_a¾€`¾¹ø ó%�ó% 8È%ÀWø˜@ð‡�‚ƒ\|…‰� 8È%ÀWø˜@ð‡�‚ƒ\|…‰�'€ƒà —�_ác"�Á à 8È%ÀW˜/ ˜/ÁA.¾Â| �Á| r ð>&täà+|L 8  ‚ƒ\|…ù�‚ùäà+Ì—�Ì—€à —�_ác"�Ár ð>&BD"˲,ËÒ.À4K€¯ð1€beeEAFÁ@.¾Â| �!D$BÑA0K€¯0_@0_‚ƒ\|…ù�ò8— £ƒ` —�_a¾€<>ŽƒŒ‚\|Å]W _C€ó% 0È%ÀWx; ˜/ÁA.¾Â×,Ã0´KhXÐA`K€¯ð5�‚ùäà+|L øC�ÁA.¾ÂÇD�‚š 8È%ÀWø˜@p@¹ø ó%�ó% 8È%ÀW˜/ ˜/ÁA.¾ÂÇD�‚€‚ƒ\|…‰�4ApK€¯0_biЀ Ì—€À —�_a¾€`¾¹ø þ@pK€¯ð1€à¹ø þ@pK€¯ð1€àpäà+|L 8¹ø ó%�ó% 8È%ÀW˜/ ˜/ÁA.¾ÂÇD�‚€‚ƒ\|…‰�4ApK€¯0_@0_‚ƒ\|…ù�‚ùäà+|L øC�ÁA.¾ÂÇD�‚š 8È%ÀWø˜@p@¹ø ó%�ó% 8È%ÀW˜/ ˜/ÁA.¾Â| �A@ÁA.¾ÂÛ1�A@ÁA.¾Âau�‚€‚ƒ\|…Ãê�ó% 8È%ÀW˜/ ˜/ÁA.¾Â| �Á| r ð>&ü!€à —�_ác"�ÁMäà+|L 8  ‚ƒ\|…ù�‚ùäà+Ì—�Ì—€à —�_ác"�A@ÁA.¾ÂÇD�‚š 8È%ÀW˜/ ˜/ÁA.¾Â| �Á| r ð>&ü!€à —�_ác"�Áÿr‰R©3f w{ôèÑeeetëZð1Ñ21 C»„† 0üË%ëÖ­ëÙ³'w»W¯ÿgïÎã¡Úÿ?€ÎÌƾ5¡,é–J!ÚT¨\¡ÒBIRiÓ"-nûr[o›«B„JJ”ut“Y*•%E¡,EÖ0˜å÷ǹw~ó‘,3sfø<ÿè1Æ™Ïç5Ó˜óžÏ9çó™‚m+ðk"x8Ôçˆ^]råʕɓ'£·­¬¬¢¢¢°Ía~M„ �O�‡úAÔ%QQQ222K–,a ðîÝ»—L&³~¼{÷®–––¢¢bll,z‚ ëÖ­CDII©ªª �ðíÛ7%%¥ššš×¯_ëèè ›ikk¿zõŠ£;AÜÝÝeeecbbØ[#‰�€äädUUUUUU …‚þ677wÔ¨Qx<¾“<™ŸcnÜ1ñöö&‘HøY³;8^A�Ž—@}“ÿôõõ) ºFï‘”” §ÓéèFFFwïÞÍÉÉÑÑÑAï�DDDÐh´+VìÞ½›ÉdîÚµËËË‹ÉdJIIµ´´ ›µ´´HIIqt�HJJJJJ2dGkL&SOOý­¾¾>ú[ccã'NP©TV Üy8ÿ2?Çܸc��sssåååÖ,Ä®°°�pàÀ¬ƒ@ÿú믿��oÞ¼Á:HÿR]] �ðõõÅ:ñ† ê"‘ØÚÚJ¥RYuÉÅ‹ÍÌÌŒ«««™L&G‡+ù7�íííL&3//OEE¥¦¦†L&£ŸwcÇŽÍÏÏG7ËÏÏ7nçS�íN\\œ£5´/ô·½‡@ 455±·À‡#ð/óslÀ;�€Á` 7~b÷éÓ'�À¾}û°ý Ö%˜¨©©�øøø`‚xCÇq´µµÓÒÒî޽˺ÇÍÍ-++KVVöÎ;��ƒ¸¸8Æ>I ��¿ýö›±±ñÌ™3GŽ9tèP�€««ëýû÷Ñm<xÀº6‡Úëp«5�€®®.Ço‡zþüù¶¶6ÖÆÜy8ÿ2?Çܸc�® :|Y xX‚�<  õ=¨}._¾,--íêêÊ>6��7n\UU“ÉÌÈÈÐ××gÏÃ,11�””„þØÜÜìêêŠÞF¯æè�°hÑ"iiék×®q·–@&“Édrbb"zϳgόњ�½§Ã<ì»’Ÿc{ŽÜ1¸Ÿ;w³»/_¾��vî܉uè_p¼��ooo¬ƒ@o Ìÿv¢ü·mÛ¶wïÞñ»#ô¨¿{é!ŒÔTTThhhüñÇþù'ÖY ��8~ü¸¯¯ï›7oСMH0ZZZ$%%W¯^}æÌ¬³@Ó ‚ ÒÒÒÁÁÁ‚éNØÀ¢„ÄÄÄ444ddd°ý ¾Ï1/˜‡úÕ%‚üÀ‚Žý„²²rYYÖ) cð:a¨P]A=V[[ÛÔÔÔÜÜÜÒÒÒÚÚJ§Óét:ƒÁ@¯WÂáp$‰D"IHHÈÊÊÊÊÊb‚ ž�õ1°.0ÖÜÜüáÇâââòòò’’’ŠŠŠªªªÊÊÊêêꆆ†úúúî6(''§¤¤¤¬¬L&“ÕÕÕ544444tttttttuuÑéõ Cÿ_jjjXõb[[FËÌÌ�\¹rESSÇ£Å"‰D’ý²²2,y‡Ã!ÇK >Cçc<xpÏž=è "ü륓sKy~Ú)•JõôôŒŒŒ�¸ºº†††’H¤^¶ÙOέ««{ùòåëׯ_¾|ùþýû‚‚‚¯_¿rl£®®®¢¢¢¬¬,//¯   +++--Šˆ‹‹ãÿƒ^AM§Ó[ZZZZZ¨Tj}}}CCCcccUUUuuuMMMee%{Ë‚èèè 4ÈÔÔÔÜÜÜÈÈ®3Ç­¼¼¼¨¨¨¨¨ˆU/–——×ÔÔ”——÷²eA444ÐzQ]]]WWWGGGKKËÌÌŒu1?Ä­²²òëׯÕÕÕuuuµµµìEakkëÛ·oedd”••Y¬¢PFFFVVV^^^QQ-ÖUUU±~6ÔAì Édò³gÏÈ×^ºR—ðjßÿ÷ß‹‰‰­\¹�ÔÖÖæííÝË6ûj]Âd2_¿~‘‘‘›››žžþáÃÖÿÅÀ ŒŒŒ´µµutt8`À�UUU L&³´´ôëׯ………ÅÅÅeee¯^½zñâÅ?Ð p8ܨQ£ÆŽ;vìØ &hkkóªkB£ÑnݺõáÇׯ_¿~ý:77—ý �‚ jjj***ªªªìõ¢”””¤¤${½ˆÃáèÿA‹EV½ØÐÐÀª?þ\^^^[[ËCMMMWW­‡ 2räHôEÿÁd2‹‹‹ ?~üX\\üåË—ÏŸ?s”×?ƒÃáº2j‚–†šššèß¶¶ö!C  Ðëg�A< ˆ}¡`ö¸½/énB ‹ððpCCC�@AA‡‡GVVV·Ò $¶¨TjtttRRÒ?ÿüÓÐÐ��Àãñ#GŽ455522233311ÁðJsssvvvnnî‹/rrrXÕ’šššƒƒƒ““Sßþú^\\|ÿþýŒŒŒ¼¼¼Ç£w"bbb¢¥¥ehh8dÈÖ~‹OõA{{;ëÞË—/_¼xññãGÖ ‡³´´DëÅ &(((ð#¶h4ZNNNzzzAA:ˆØÞÞÎú-‡6l:¶¤¦¦†"***ÊÉÉÉÊÊÊÈȰ"²Þ®4­Ã¢°ºººººúû÷ïeeeååå_¿~}óæ {#..>zôh SSScccôŒZ4~OÂÞQRR’ŠŠŠŠŠJrr2ë·ÞÞÞbbbìIKK0`€‚‚BLL {;þþþèÏŸ?g}bm°víZ ‰ýû÷sgัgÏeeeÀuñN‡½s·,%%ÅZO§Ã5zØÛïð‰w˜ŸÉd†„„ìÚµ‹;† ÿËzãû÷ïÛ·o733CÇ<ðxü”)S¶mÛvÿþý¶¶6¬ÓýÔ?âããׯ_?jÔ(Vò… †……577cŽgÚÛÛ“’’|}}Ìz;™˜˜,_¾<((èîÝ»èRØjkk»}ûöÑ£GçÎËdÅápæææ»víÊÉÉA—k]mmm×®]Û´i“¹¹9«˜@ÄÐÐÐÝÝ}×®]—/_~þüùÏ–°à­ÊÊʧOŸ†……­[·ÎÁÁAWW—õÆŸ4iÒŽ;bbb„áõ‚ØÉ±v¥.VÇZQågëÕååå©««£·¹Û\ëÞq`ÝàXW}gßá"‚-ÿrí@Žö»²X � ,,lÛ¶mÄ` +*•zùòå‰'¢Ÿhd2ÙËË+%%¥“• …V[[Ûõë×çÌ™#%%…î0ïܹ#º»ÃÖÖÖ›7o:::¢u0‚ #FŒðõõ½|ùrkk+Öé~¡¤¤$$$dÉ’%òòòè»KSSsÆ ?Æ:Z÷|ùòåÈ‘#vvv¬Á'mmmww÷Ó§Ogee OùÛÐÐpïÞ½£G.Z´ˆuÚwpp@'°† ¾h]Òábu¬õX¸×«Ûµkz?ëîÅö�׺wÜX78ÖÕcH‡‹r´ü˵¹öûåb��}}ýúúúNb0…OUUÕîÝ»�bbbK–,¹wïžèîÂÙQ©Ôk×®9;;£#(ƒ>þ<{))ü 6nÜ(''‡þí̘1#((Htw->|Ø·o«üÕÕÕ=qâDMM Ö¹:SRRò矲¨”••.\^RR‚u´.ÉÉÉ9{öì¬Y³XŸÀþþþß¾}Ã:Ôg z¼„B¡P(===Ž_±322JLLdÿª-!!ñìÙ3ô*DôccãS§N±Ûã.>:ÿF?~üÕ«W™L&‘H,++ûYïÜ÷÷÷?wîz;00ðìÙ³ÜÏ‚½}î'ÞaþÔÔTGGGtôˆ;{HaPWW÷ǠߨÔÔÔNŸ>-ÌGjz£±±ñÀèIJ***/^þÂ+33ÓÞÞ­¨ÌÌÌþúë/áùFÞ{ÕÕÕ»wïF÷”{÷îå¨ò1Ç`0.^¼8}útô¿@FFfÓ¦MÂÿÎùöÏ?ÿ¬[·ý“'óæÍC?ß ˆ·Z—t²X;îõê¼¼¼$$$V­Zź‡{±½nÕ%hã¬uõXlöÎ}£+k²·ß•ÅÁç— ëoqÇ`‰ùØIDD:®nhhxóæMlÃN¿pá™LF¿© íq„/^L›65|õâÅ ¬ñ ƒÁ¸qãÆ¤I“ÐÝäöíÛ¹ÿN§;v Awwwg­9Ú7 /û¬Y³Ð³bÕÔÔ°õ)Âxh�fß¾}3f z˜?>>ë8‚F¥R>,))‰Ãá:$T_[[[·lÙ‚ÃáˆDâêÕ«ËË˱N$ 999ãÇ�H¤'N`˜äÆzzzèÞúðáõµµ†á·ŠŠŠmÛ¶¡ßOLLLÞ½{‡u"¨€u Ô yyy***‚¬]»VØFÎéóçÏèYÆÆÆBr~ÃÓ§OÑ+i­­­?}ú„u Ü¿=cÆŒ‚?hU]]=uêTôHßéÓ§…ÿ„b^illܽ{7z”ÓÝÝýÇX'‚D¬K ®zùò¥ŒŒŒ´´4ëjçþŒN§oÚ´ � §§÷ýûwlÃܼySLLLVV6<<Û$Ø¢R©Ë–-�(**¬ßG)(( ²råÊþY¯ÿþÝÍÍ �0`À�8põ¬K .)++#“Érrr¹¹¹Xg"çÎCO,Åðœß¸¸87hÐ Q¹Äƒß®^½ŠÃádeeÑéòøíï¿ÿFDKKK0Ý ³˜˜"‘ˆÃáØ§ž‚ î‚u Ô%¶¶¶x<>;;ë Bg÷îÝ�€`ÒûóçÏÅÄÄôôô„äp’HMMÅãñ |í(((�`jjÚØØÈ׎DEUUÕàÁƒIHHÀ: $ª0˜Ú\çSÂHB%55ÕÖÖvÆ 'OžÄ:‹Ða0£F****--E¯Â˜¶¶6CCÚšš÷ïßÃÅØ8„‡‡{xx¬]»öï¿ÿæSéééVVV£GÎÈÈçS/"§±±ÑØØ]‹jÈ!XÇDß—ÅBþ¿»ƒø!44”H$¢·ÿþ¦¦¦k×® ¸ë+W®ïß¿%Ü–,Y2qâÄ   ²²2~´O§ÓÝÝÝ%%%`QÂNFFÁÃÃë,Hâ{]‚Ë€ÿ8DÀ"©ë222ÆŽËšâ0cÆ "‘˜‘‘!à~###åååW¯^-à~EÅž={ÚÛÛùT/FDDŸ8qB]]í‹´aÆùøø<zôèÁƒXgD6ˈ{{{“H¤ ?Þ½{WKKKQQ166½gïÞ½d2™U:poÀA¹† <�� �IDAT‰Ä­EdݺuèZµ?{ Ú2ûÎ/#±?ÖÝÝ]VV6&&†»ÇäädUUUUUU …‚þ677wÔ¨Qè¤ò]|¾¿|úð[UU•¦¦¦`úEbbbd2YLLLÀý¢óvôíu{cÒ¤IâââOŸ>åGã±±±$ÉÝÝ÷ëׯ�tø‰ A¿ ˜ÓXØ;\Ëàq¯QDZîÝÏVòca_Ò°­ØÉ»‰}ct¾!C†p÷Ø•%ú~ù|ùô96à7UUUkkkÁô%Šèt:‰Dš;w® ;e0h‰,ÈNE™L^¶l?Z8p ••?Zî3´´´&OžŒu Hô`S—p,ƒÇ½F÷ºw°p/éØÖìäÝľ1ºŸ¸¸x‡=þr‰¾_>ß_>}Ž øÍÁÁARRR&ùNiii�€ãÇ ¸_uuu¸kìDss3_ºt)?WQQ±³³ãGË}†Á¼yó°N‰lŽãp€000ˆ‹‹£Ñh ½ÇÍÍ-++KVVöÎ;nÀrôèÑ{÷îeff2ÙN^alwò@"‘X^^ÞõHìÒÒÒîÞ½«££ÃÝ£®®.Ço‡zþüù¶¶¶®?ß_>}Ž ømñâÅÍÍÍÇŽ@_¢h×®]D"qþüùîwâĉYYY555îWTܸqƒN§³Öæ-mmí¼¼<~´Ü7´´´”””àpØìb Ñ&˜òüïàÇ—ÊlëÞqoÀ½¤û6<°Ãeð:‰ÄžÑ¢EÒÒÒ×®]ãî±+KôýòùþòéslÀo4ÍØØXBB¢¨¨H�݉–ÀÀ@�À† ß5Z•®Y³Fð] ¿ÖÖV}}}>ÍŒþÇ��²²²øÑxpéÒ%�@hh(ÖA Ñçíè¶þ9ÙIAA‰‰‰¼¼ü“'Oà9°,‰‰‰ŽŽŽèWg)))Á°··OII¹}û6º8 ÄâíípæÌ>]¯ôõë׎5*++ Ž phnn:tè?¾|ù"!!uHÄÀ?'¨K “’’ªªªÆŒ‡¯Q¡¡¡ŽŽŽŠŠŠ÷ïßǤ(A3¨©©9::fffb@8mß¾= `ÆŒ+W®äSªªªÛ¶m{üøñÎ;ùÔ…èòôô,))9qâ,J žÀzÀ%÷îÝ#‘Hâââýõ—À®B®®®��55µââblü}ûVQQQBB"** Û$ µµÎk̘1ü^Û¶½½}Ê”)�€S§Nñµ#Ѳ|ùr�€‡‡ÖA Që¨{Þ¿Ç=zô‹/°Žƒ«W¯jhh��æÍ›'$ËÙøðAKK �àîî^WW‡u̼}ûvذa��+++Á¬ë[__?~üx�ÀÒ¥Kûs¥Žª©©;v,ú§áJ–¨ƒu Ômt:ýàÁƒbbb‚ÌŸ?¿ÿ,k~ûöíáÇ�ää䂃ƒ±Žó?êêê\\\��ŠŠŠ‘‘‘èuïýG]]¯¯/@ ‰çÎd×MMMÎÎÎ��--­œœAv-Tnß¾®µiÓ&t2'êA×%B~䨥¥ÅÕÕ½íââÒÜÜüˇù3âŸ?ººº¢³ªÌœ9366ëDüB£ÑÂÃÃÑ ¿%$$>,´ß)Ššš�@SS3""¢?T'­­­'OžDÏï5jVUrhh¨””‚ [·nå÷ñ#aS[[»víZ�€²²2ë:Dê1X—üÖ—­ÀÀ@ÿ_>tt}rÿñæÍwwwtúyyù;vfª7ÁxüøñÆÑs÷dee·oßþíÛ7¬CýBSSÓáÇåääÐÿtMA¬CñÅׯ_7mÚ„®ÿ §§—€mž’’’Ù³g�‚OMM ¶y ¢¢bõêÕ8‡Ã­X±¢/ýíCÄ®t4yI·�öîÆŽËú¾õîÝ; ‹n=¼gö0`�z2õرc<øöí[¬sõPNNΦM›tuuѧ3bĈÐÐPÑÚ»744?~ýÁáp³gÏŽ‹‹Úažn©««;{ö,ëºhSSS …‚u¨ÿ÷øñct&7AœïܹÓ÷F­h4Ú7ìííÑÿ‚©S§æççc ê;ø¾wä¸ö�°víZ ‰ýû÷³o#!!Ntr­ûfL&óùóç#GŽDgøÙ=iii PPPˆ‰‰a5²xñb™ëׯsw'%%ÅZȦ¥¥EJJŠ#wÜ7:ì”ýY÷Õë¡ Fzzú’%KX˾ËÉÉ-]º4 �ó‹V:Ç`0^¾|yüøñY³f±®lœ4iÒîÝ»?þŒuºž£Ñh öööè´~’’’ ,ˆŠŠ’Óu»¥   88xòäÉx<“pwwÿðáÖ¹:–——7kÖ,ôe×ÔÔôóó{üø1Ö¡xàáÇk×®URRBëÝ… &%%IHHìÞ½»ï•_V0/áX!űðÞÏšbߌ{=¼®¬:Zuµ½””k˜ëî.¸ë’;åxÖ}¬"áÀ`0²³³8`jjÊšà_CCcΜ9‡ºqãFEEæ £££ÿøã[[[yyy4¤˜˜˜­­íñãÇkkk±MÈ[MMMGޱ±±Awꂌ=zåÊ•ñññÂüLKKKÃÂÂ/^ÌšFBBbÍš5ñññ"qfe}}ýöíÛѳA� [·nMII­«–––ØØXiiiÖÕþýûÑÓïjkk­¬¬��îîî¢õ¼ ¡%ˆ©KÙ'HE]•uçîÝ»O:ÕÐЀþ üdBUîÍÄÄÄêëë%%%YÛp߃ž÷€nÏjý²(''G¥R9º³°° 2d�àÝ»wË–-ËÈÈ`ÁÝëá¬vÊñ¬ûϤ±uuuééé¯^½ºsçNGï'“ÉFFF†††FFFÔÕÕ8p ²²2?2|ûö­°°°¸¸¸¬¬ìåË—/^¼ÈÏÏg-6D$mmmÇŽ;~üxssó¾=F£P(III©©©ÅÅÅèƒ655522233355E¿ N/,,|õêÕ‹/rss<xÐÜÜŒþjèÐ¡ŽŽŽS§N2e ÇRV"B¡dggÇÇÇ¿~ý�€ Ș1clmm'L˜0eÊ111¬rjkkKMM½wï^ZZÚË—/™L&‚ æææ®®®¬…µñÒ¥K###­­­cbbÐs› ¨Ç±wÿôé:å÷Ž™D"effR©ÔqãÆ¡÷°oϽو#–.]ºjÕ*ôÄ·ï:tèÑ£GíììXE#B¡P��7n|÷îGwÿý·˜˜:GdPPƒÁ@WÞaáî‚ûuØ)Ç6>Ç>Édfff½~ýúÕ«W¥¥¥ìàp8mmmUUUeeeyyy999)))IIItJ7tueG§Óét:ƒÁhiiiii¡R©õõõ UUUß¿ÿþýû—/_ÊËËÙßä‚êêêšššš››2dРA%„B]]]rrrnnnzzúóçÏY%#‘H1b„‘‘‘¶¶¶ŽŽÎÀ555544x¸¿ùöí[yyùׯ_?|øP\\\QQñâÅ‹‚‚V ‰ &˜™™7nòäÉ}¦X¬¨¨HJJºuëVrrrkk+zçàÁƒŒŒÌÍÍÍÍÍuttôôô\{1Œ'Ož|ùòåÕ«W¹¹¹/^¼øòå ú+mmm {{û3f°~¸1™Ì;v<xpøðáÉÉÉèl:Ô3‚¨KÖ¯_þüyôø÷zåÊ•è…0Û³áÞìùóç¯_¿FG~:¼'33ÓÃÃãÇ࿳[Y´hQ\\\hhè¼yó8ºkiiY¶lYdd$�`áÂ…¡¡¡ˆÜ]p?£;å¸Ñásì‡ ÆÛ·o?~üøéÓ§òòòÒÒÒòòòêêêÊÊÊÞ,“‹ ºz¢ººº††††††ŽŽŽŽŽŽ–––‘‘‘(~áæ·¶¶¶üüüW¯^½zõêýû÷EEE4}qqqUUUV½(+++---)))!!Áªñx<ºð5N稿}ûöýû÷ªª*Ž–%$$†Ê^/ª«« öÀÀû÷ïŸ>}š™™ùàÁƒ7oÞ°îGdøðášššººº:::èXMML&÷f@‘Éd¢¯YYYyyyeeeQQQqqqeee^^ëƒHFFfĈèÿ‚ƒƒº¸i?~õêÕªªªÉÉÉ#FŒèqT¨Ÿë/GXúÏ”> ¦¦¦¶¶¶¡¡¡©©©¹¹¹¥¥¥­­F£¡Ã$¬¡„„‰D’•••“““••UPPÀ:»Èc2™¥¥¥ÅÅÅõbuuu}}}MMMccc×[SPP““SRRRVVf¯Ñ]/™LæÛóË—/ ñôôœ2eJaaáû÷ï ‹ŠŠª««¹7VTTä( %$$ÐD<OÿOCCC{{{[[[Ã:,ôÕÕÕuttÐ’ñôéÓfffººº½)ÜSRRæÏŸ Httô´iÓzÜÔŸõ»4¬K ˆWšššššš¨Tjkk+ë°ë@‰DBëE¬5 ܾ}û¼yó¢¢¢8Ö%f0ïß¿ÿüùsyyyUUÕׯ_«««ëêêÞ¿_[[+))I¥RÙ_|:޾øL&“J¥ª¨¨ÈËËËÈÈ õ:«(TSSC‹B´9|ø°ŸŸ_ll,:ÿJ/åææÚÛÛWUU.]º´÷ Bý ÜICa#22ÒÍÍmܸq©©©]?‡ÆÔÔ´¸¸øË—/¬ ò9¤¤¤ØÙÙ]»v =TýKõõõÚÚÚOž<éjôN•––ÚÙÙ½yófçÎ{÷î…GN¡nÁýz‚ ˆ×îß¿ïé驯¯×õ¢äéÓ§OŸ>eŸ%ˆz\¬ªªª‹mÊÉÉ­^½:'''--­‹éÜÀ322¦L™²ÿþ%K–´µµñ¤Y¨Ÿ€u A åççÏž=[VV–B¡tëÂì   A¼¼¼:Ù==¶ëu �`ýúõ$éСC]HçäååSRRÜÜÜ.^¼hggW__Ï«–¡>Ö%AUYYigg×ÚÚš0xðà®?°¾¾>**ÊÚÚZOO¯“ÍÐñ’O›ýUUÕ¥K—¦¥¥åäätýQ#‰;vìHKK?~<Ǥ�ô3}¹.5!6MMM3gÎ,--½|ùòرc»õØK—.555u>X�@çûéÖx �À××—@ ðpÈ�€ ÈþýûCBBÐåÆ^¼xÁÃÆ¡¾ª¯Õ%ìµ<¥‚ ¡B§Ó]\\ž>}Š.ÆÔ݇ihh888ürK2™ÜݺDGGÇÅÅ%>>>??¿»Á:çéé™””ÔØØ8qâÄ[·nñ¶q¨ïD]’››;jÔ(<Ï*’““UUUUUUÑ©W�‚x{{“H¤üìž»wïjii)**ÆÆÆvØ2ë_ö»ØÝÞ½{Éd2b ˆÖ¯_Ÿ˜˜¸~ýú 6t÷±yyyžžž]™·¾u �`ëÖ­L&óèÑ£Ý}à/M›6-==]FFfæÌ™!!!<oêSx±ÈÎ/p¯u§§§‡.ž§¯¯Ïš8•{e;Ž{¸×Ãëd=öÛ]éNRR2<<œN§óüéC1™ÌcÇŽ�œœœzö9³páB<_RRÒ•g̘¡ªªÚƒ^ÄÄĺØKw•––6 �°}ûv¸þ0ô3‚¨KBSSû=x<¾µµ•J¥„s�€¾MÛò¼÷ S±V¿ë°åë’®twñâE333ccãêêj^=q‚ Ttt4‡377çøÈꢪª*qqñ™3gvq{777Ѓ}vv6�`ݺuÝ}`ÕÕÕM:�°hÑ"t Uâ ˆã8C‡=þ<û%캺ºiiiwïÞÕÑÑaÝÉ} …ヸ¸8tõŸµL$ËËË9ÚéJwnnnYYY²²²wîÜéþS„ ú©¬¬¬Å‹ëèè$$$°¯FÞuááá­­­è’¢]A&“i4Zmmmw;;v¬••UHHHu…œœ…BY¼xñåË—§OŸ^WWÇ^ Ñ&€ÚçÙ³gÆÆÆh€Þ“€.«–˜˜ˆÞ؆I~v###C__Ÿ=6wËëÖ­Cšb`»�Œ7®ªªŠç¯�AýÖû÷ï••••””Þ½{׳ †žžžŽŽN×�¡—Õô¬Çþù�°cÇŽ<¶‹ Æ®]»��¿ýöŸŽA¢ ÎCAÄ/UUU–––_¾|¹}ûö„ zÖHjjª­­íŸþùÇtñ!¡¡¡Ë–-{øðáøñã{ÐãèÑ£?}úTRR"##Óƒ‡wÑ… V®\©¬¬œ””dbbÂ¿Ž ÑÒ×®† ---ŽŽŽEEEááá=.J��AAAbbbÝZ¯»SÑsضm[mmm```ÏÞEK—.MJJjjjš4iRJJ _û‚D¬K ‚xÁ`¸¹¹egg>|xþüù=n§¼¼<!!ÁÉÉIMM­ëêÁTôìæÌ™c``pòäI*•Ú³ºÈÖÖ6==]NNÎÁÁ!88˜¯}A¢Ö%A¼·yóæØØØ•+WnÙ²¥7턆†¶··wýŒWT¦¢g‡Ãá¶lÙRQQѳºnĈ=:t¨——×öíÛá©<¿‚ ˆÇþþûïuëÖýþûïqqq¡ÇíÐéôAƒ‘H¤üüünÍúXWW§  °aÆ“'Oö¬ë¶¶¶Áƒ‹‹‹àñøž5ÒuõõõÎÎÎwîÜY¸pahhh'«%C}/ â¥øøø7š˜˜\½zµ7E �€B¡”––®X±¢»SQËÉɉÄÞ\ëK$}||ŠŠŠ¢££{ÜHס×/Y²$22rúôé=¸Âê3àx AÏ<yòdòäÉd29;;[]]½—­ýþûïwïÞ-++STTìîc555‡ †^ôÛ3?~üÐÑÑ0`@nn®`Öè`2™{÷îÝ·oŸ‘‘…BÑÖÖ@§°ã%A¼ñéÓ'"‘˜œœÜû¢¤¸¸øÖ­[óæÍëAQ�PVVîåÜhÒÒÒÞÞÞ/_¾ØÅ2‚ìÙ³çÂ… >|°°°xöì™`ú…„ ¬K ‚x ¦¦ÆÎή¶¶666ö·ß~ë}ƒçÏŸg0^^^={8™Lîñy¯,k×®•––Fgi˜%K–$''755YYY%'' ²kHÀº‚ ¨·Z[[gÍšUPP2eÊ”Þ7ØÞÞ~áÂcccKKËžµÐ³%…9())­X±"#####£—Mu‹ÍÇåå圜‚‚‚Ù5„9X—@õ “ÉôððHOOß»w¯››OÚŒ‹‹«¬¬ìîåÁìÈd2•Jmllìe"‘(à!�€±±qvvöo¿ý¶råJ???x*dÿë‚ ^Ù¾}{TT”‡‡ÇÎ;yÕf`` ´´ôÂ… {ÜB/§|eÑÔÔ\¼xqJJÊË—/{ÙTw 0 ==ÝÖÖöðáà .lmmp�°. ê¹àààC‡ÙØØððpCAAÁ½{÷\]]eee{ܯê�ÀæÍ›q8ÜáÇ{ßTwÉÊÊ&%%yxxDEEM›6 ^?ÜÀº‚ ¨‡RRRÖ¬Ycll#&&Æ«fƒƒƒ™Lfoâ€^OEÏÎÀÀ`öìÙׯ_/**ê}kÝ%&&váÂ…½{÷¦§§7®¸¸Xð A‚u APOäææÎŸ?_UU599¹7¨Tjxx¸™™Ù¨Q£zÓN/§¢ç°mÛ6ƒqìØ1ž´Ö»ví +**²°°xúô)V1 €u AP·•––ÚÛÛ�’““ ÀÖ£££kjjz9Xxz�`bbbkk^QQÁ“{ÀÝÝB¡´´´XYY%%%aâ7X—@uO}}ýï¿ÿþíÛ·ëׯ1‚·)((ôf boë�€ŸŸ_kkkÜቩS§>|øPQQÑÉÉéܹs&øÖ%AÝÐÞÞ>gΜ¼¼¼sçÎM›6·¿zõ*++ËÍÍMRR²—M)**âp8Ö%“&M²°° ÄöäÓáÇggg>|õêÕ[·n…×÷=°. ê*&“¹|ùò´´´íÛ·/[¶Œçí"Òûƒ8��<¯¨¨Èú�àççרØxæÌ¶ÙšššéééÓ¦M;zô¨««+¼~¸ëöAuÕž={öîÝ»páÂK—.ñ|)»?~hjjŽ5êþýû<ipèС²²²=âIk��&“illüõë×âââÞèôR{{ûªU«BCC'L˜׳U„ !ÇK ‚º$""bß¾}VVV¡¡¡üX_÷Ê•+ <,Añd*zv‚lݺµªª*$$„‡ÍöŒ˜˜XHHÈþýû322Æ÷éÓ'¬A¼ÇK ‚~íÎ;vvvzzz™™™ üèÂÄĤ¬¬ìóçÏD"‘' :;;ß¾}»¡¡'­¡h4šN/,,äá”-½qéÒ¥eË–)(($&&šššbê-8^Aô yyyÎÎÎJJJ …OEÉ“'Orss=<<xU”��Èdrcc#•JåUƒ��àëë[ZZÉÃf{ÃÍÍ-%%¥µµuòäɉ‰‰XÇz Ö%A)//·³³£Ñh‰‰‰:::|ê%00‡Ã­X±‚‡mòüRa”‡‡‡ªªêÑ£G o[î±)S¦<|øPIIiÖ¬YgÏžÅ:Ô+°. ú©ÆÆF{{ûòòò¨¨¨1cÆð©—ÚÚÚk×®ÙØØ 4ˆ‡Íòp*zv$iÆ ùùùqqq¼m¹7† –mll¼fÍš-[¶OÍu¬K ‚:F£ÑæÏŸŸ››ëïï?sæLþutñâÅææfžñŠâíTôìV­Z%''‡ÉJ~ÐÐÐxðàÁôéÓ;æââÂÛXÀÀº‚ ¨ckÖ¬IIIñõõ]½z5ÿza2™AAAšššèÄö<ħã8��99¹Õ«Wçä䤥¥ñ¼ñÞ‘‘ILL\¾|ytt´Í÷ïß±Nu¬K ‚:pèСààà¹sç9r„¯¥§§ççç/[¶Œ@ ð¶eþÕ%�€õëדH¤C‡ñ£ñÞ ÁÁÁÈÌÌ7nÜDZNu¬K ‚8EEEmß¾}ܸq/^Äáøû9H ø1{,_ëUUÕ¥K—¦¥¥åääð£ý^Ú¾}ûÅ‹?}údaañäɬã@Ý�ë‚ ÿ‘žžîáá¡§§'!!Á×¾¾}ûvãÆ {{{Þ.JŒRVVF„Ou �À××—@ á jÑ¢E·nÝjkk›<yr||<Öq ®‚u AÐÿ{÷îݬY³dee) z= _………µµµyyyñ£q"‘(++Ëó^Q:::...ñññùùù|ꢗ&Ožœ‘‘A&“çÌ™€u¨K`]Aô¯¯_¿ÚÙÙµ´´ÄÇÇëééñ»;ƒ<hÐ [[[>uÁó©è9 +ú=z”]ôÒo¿ý–=bÄooo___xý°ðƒu A��477Ïœ9³¤¤äÒ¥Kè155õãÇ+V¬àß),ü®K~ûí·™3gFFF–––ò¯—^RWWðàÝñãÇ,X�¯r°. t:ÝÕÕ5''篿þš3gŽ`: $‰üë‚ßu �ÀÏϯ½½ýøñã|í¥—¤¥¥ãããW¬Xqýúukkkxý°0ƒu AذaC||¼··÷ÆÓcYYYRRÒìÙ³UTTø× ™L®­­¥ÑhüëbìØ±VVV!!!ü.€z‰@ <x0++ËÒÒ²¨¨ëDPÇ`]APwâĉ€€�GGÇ“'O ¬ÓÆó9^9(++3™LþúŠòóóknnö÷÷çk/<áççwùòå’’KKËÇcê�¬K ê×bcc7oÞlffvåÊ</˜Ni4ZHHˆ‘‘ÑĉùÚÿ¦¢ggkkkbbræÌ™ÆÆF¾vÄ®®®·nÝjooŸ2eŠP-ñ¡`]APÿ•íææ¦­­ )))°~“’’¾|ùâåå… _;âëÔjì¶mÛV[[ÈïŽxÂÊÊ*##CEEÅÙÙY$†yúX—@ÔO:::’H$ …¢ªª*È®ƒ‚‚$%%/^ÌïŽV—Ì™3ÇÀÀàäÉ“¢rµËСC³³³G޹~ýzxý°ð€u AýQuuµ]CCÃÍ›7‡ "È®?~üxûöíyóæ)((ð»/Õ%8nË–-üî‹WÔÔÔîß¿ÿû￟<yrÞ¼y---X'‚�€u Aý•Jutt,,, ã÷Ü‚ƒƒ ¿ÏxE¡SÖ æJ77·;vŒN§  ;ž––Ž‹‹[¹rell¬µµ5¿OĺÖ%õ/ ÃÍÍ-++ëàÁƒ...î½­­-,,lÔ¨Qæææ芴!�� �IDATN0ç½¢ˆD¢OQQQtt´�ºãpîܹÇggg[ZZb¨¿ƒu AýË–-[bbbV¬X±mÛ6Á÷~ãÆoß¾ñiAnRRR’’’›YdùòåJJJGŽa2™‚é‘W¶nÝŠÎZkii™uœ~ Ö%õ#gΜ9~üøŒ3Μ9ƒI€ÀÀ@YYÙ…  ¬GLùÊ"--íííýòåË””ÁôÈC...·oߦÓéS§N½qãÖqú/X—@Ô_$&&®_¿~Ô¨Q×®]#‚ŸŸŸžž¾páBiiiu*Ⱥ�°víZiiéC‡ ¬Gš8qbFF†ššÚܹsOŸ>uœ~ Ö%õ OŸ>uqqÑÔÔLJJ’‘‘Á$CPP“ÉØA”€ë%%¥+Vdddddd¬S222ÊÊÊ211Ù°aÆ àõÂë‚ú¾âââ™3g„ääd L2477_¼xÑÂÂbĈ‚ìWYYùû÷ï‚<áÃÇLJH$Šè øïúa{{ûÓ§OÏ;^?,`°. ¨«­­µ³³«©©‰6lV1¢££kkksy0;2™L£ÑjkkÖ£¦¦æâÅ‹SRR^¾|)°NyKJJ*..nÕªU7nܘ:uª/IØÇÀº‚ ¾¬µµuÖ¬YïÞ½ ž:u*†IçÎ+à~6µ»Í›7ãp¸Ã‡ ²SÞÂãñgÏž=räÈãÇ---?|ø€u¢þÖ%õYL&ÓÓÓóÁƒ»wïvwwÇ0InnîãÇÝÝÝI$’€»Æ¤.100˜={öõë×‹ŠŠÙ/ÏmÙ²åÊ•+_¾|±´´ÌÊÊÂ:N¿�ë‚ú¬;vDFF.Y²d×®]Ø& BDÀg¼¢0©K��Û¶mc0ÇŽp¿<7þüÛ·o3 kkëØØX¬ãô}°. ¨o 9xð µµupp0¿—íí\CCCddääÉ“ ß» §¢ggbbbkk^QQ!à®yn„ ™™™jjjóæÍ;yò$Öqú8X—@ÔݺukÕªUlj‰Ã6Lddä?0,‚ŠžƒŸŸ_kkkߨ‘2$;;{ôèÑ>>>ëׯ¡5€D"r³CuîÅ‹'N”‘‘yôè‘––ÖqÀÈ‘#+++KKK‰D¢à{¯««SPPذa&õ¥¥e^^^II‰�O€¦¦&WWׄ„''§ÈÈHIII¬õAp¼‚ >åóçÏööö�€¤¤$a(J²³³_¾|ééé‰IQ�““#‰X]éêçç×ØØˆÕ¬ÿ<'%%uãÆ5kÖÄÅÅM™2åÛ·oX'êƒ`]APßÑÐÐðûï¿ýúõÚµk£FÂ:��âp¸åË—c�Aeee¬ê{{ûaÆùûû777c€çðx|@@À±cÇrrr,--ß¿u¢¾Ö%õíííÎÎί_¿>{öìŒ3°Ž��555ׯ_Ÿ>}ºŽŽ†10¬KÙºukUUUHH&øÄ××7**ª¬¬ÌÒÒ233ë8} ¬K ê#¼¼¼RSSýüü0œàÑÒÒ"ø9^9ÉdLÎ{E-X°@WW÷øñãíííXeà‡y󿥦¦�¬­­¯_¿Žuœ¾Ö%õûöí sqqùóÏ?±Îò/&“¤¥¥egg‡m/ÝÇ@ øúú–––FFFb•OÆŸ™™©¡¡±`Á‚ãÇc§€u A"ïâÅ‹{öì™8qbXX¶S•°»wï^AAÁòåËñx<¶IÈd2•JmllÄ*€‡‡‡ªªêÑ£GûÞò¼†††ÙÙÙ¦¦¦¾¾¾ÞÞÞðúáÞƒu A¢íîݻ˗/744¼y󦸸8Öqþ_PP@ðôôÄ:fS¾²H¤ 6äççÇÅÅa•TTTîÞ½ëèè0gΜ>s†/V`]A{óæÍœ9s(Š¢¢"Öqþßׯ_ãââ444°Î‚}]�Xµj•œœœH¯ä× IIÉØØXooïøøøÉ“'Ãë‡{Ö%‰ªŠŠ ;;»öööÄÄD]]]¬ãüÐÐж¶6ÌÏxEa5=;99¹Õ«Wçä䤥¥aƒðx¼¿¿ÿñãÇŸ>}jaaQPP€u"Që‚DÒ?ìííËÊÊ®\¹bjjŠuœÿÁ`0Ο?¯§§gmmu�0ŠžÝúõëI$Ò¡C‡°ÁW>>>×®]+//7n\FFÖqD¬K =4mþüùÏŸ??uꔃƒÖq8ݺu«¸¸xÅŠBr®0Ç�¨ªª.]º4---''Û$|åìì|çÎAlll¢££±Ž#z`]AèY»v-…BñññY»v-ÖY:(..îááu I]�ðõõ%}{È�0nܸÌÌLMMM—cÇŽaGÄÀº‚ säÈ‘   9sæç'þçÏŸ)г³3zV‡0PTTÄápÂP—èè踸¸ÄÇÇçççc…¿ ²³³ÍÌ̶lÙ²fÍxýp×Áº‚ QrõêU??? ‹K—.ápÂø vþüy:îåå…uÿ‡Çã…¡.�lݺ•Éd=zë |G&“ÓÒÒfÍšuöìÙY³f555aH4 L&ë A]òðáC--­ììlá`G£Ñ´µµòòò°Îò?†*++ûèÑ#¬ƒ��€££cJJJaaáÀ±ÎÂw cãÆþþþ¦¦¦‰‰‰ªªªX'vÂøm‚ ˆ[AA“““ŒŒ …B΢�P^^.$—³Ãv*z~~~íííýdâvwúôé'N<{öÌÂÂâÝ»wX'v°. H|ûöÍÎή¥¥%>>^__ë8?(%%åææ†uNBU—Œ;ÖÊÊ*$$Dx"ñÛÆ£££+++Ç÷ðáC¬ã5X—@$ìš››Š‹‹/^¼hii‰uœŸ*,,¼sç΂ äää°Î‰L&766R©T¬ƒüËÏϯ¹¹Ùßßë ‚3gΜ´´4gccsõêU¬ã/X—@$ÔètúÂ… ?~|ôèQggg¬ãt&88˜Éd áA L— £lmmMLLΜ9ƒáj‚‚gaa‘••¥¥¥åêêÚÎüíX—@$Ô|||âââÖ¬Y³iÓ&¬³t¦µµ5,,lôèÑcÆŒÁ:K„a*zÛ¶m«­­ Ä:ˆ@éëëgee;vëÖ­«W¯†×sƒu AÂëÔ©Sþþþ3gÎ<}ú4ÖY~!&&¦ººZ8K€ÐLEÏnΜ9'Ožž£K‚^?<{öìsçÎ999Áë‡9Àº‚ !uãÆM›6™ššFEEáñx¬ãüBPPœœœ‹‹ ÖA:&lÇq��8nË–-Xg4‰týúõ 6$%%YYYUVVbHˆÀº‚ aôèÑ£E‹ 8011QJJ ë8¿ðæÍ›‡.Z´Hh£ a]�pss0`À±cÇúáá wòäÉS§N=þÜ¢ÏO€Ûu°. Hè988HHHP(‘˜‡ =IBhâ�a­KˆD¢OQQQ¿]ßnýúõ111_¿~7n܃°Ž#`]Apùþý»]CCÃÍ›7ŒŒ°ŽókMMM—.]?~ü°aðÎòSÊÊÊ‚[]�X¾|¹’’Ò‘#Gúíäã³fͺ{÷.@˜6mZTTÖq°ë‚„•JurrúðáÃ… &Mš„uœ.¹zõj}}½P-ˆÃH$ÊÊÊ Õy¯(iiiooï—/_¦¤¤`3cÇŽÍÊÊ8pàÂ… >ŒuŒÁõq  ÃÅÅ%::úÏ?ÿüã?°ŽÓU¦¦¦ÅÅÅŸ?–À:KgôõõÕÔÔ„p²Ñïß¿ëèèŒ9R³ Ruuµ££cVV–——W@@�@À:6àx AÂbÛ¶mÑÑÑË—/¡¢äÙ³gOŸ>]²d‰%@Ȧ¢g§¤¤´bÅŠŒŒŒŒŒ ¬³`IYYùÎ;ÎÎÎAAANNN?~üÀ:6`]AP8wîܱcǦOŸ~öìY¬³tC`` ‚ +V¬À:ȯ m]�ðññ!‰‡Â:ÆH$Òµk×|||’““­¬¬***°N„X—@„½¤¤$ooï‘#GFGG‹Ððu}}}TTÔÔ©S…y)A2™\[[K£Ñ°ÒMMÍÅ‹§¤¤¼|ùë,ÃápÇ÷÷÷ñâ………ÅÛ·o±N$h°. cÏž=[°`††FRR’ŒŒ ÖqºáòåËMMMÂ|y0;eee&“)„§¾¢6oÞŒÃáàYŸ(oo˜ªªªñãÇß¿ë8ë‚°TRRbooO ’““555±ŽÓ=êêêXé!œŠžÁìÙ³¯_¿^TT„u¡àäät÷î]11±éÓ§GFFbGp`]Afêêêììì¾ÿ3|øp¬ãtOFFF^^ž§§§˜˜ÖYºD8§Vc·mÛ6ƒqìØ1¬ƒ ssó¬¬,mmm77·ƒbG@`]A6ÚÚÚfÏžŸŸdmmuœn ÄãñË—/Ç:HW ]bbbbkkÞ?Ï÷ìÐàÁƒ³²²,--·oßîåå%œ§ñ¬K Â�“Éôôô¼wïÞÎ;=<<°ŽÓmÕÕÕ±±±vvvÄ:KW ]�ðóókmm=yò$ÖA„ˆ’’Ò;wæÎ¼oß>¬ãðÈœ÷AP_²k׮˗//^¼xÏž=Xgé‰ððp*•*äs¼rPVVB_—Lš4ÉÂÂ"00ÐÏÏOAAë8‚óèÑ£êêê²²²²²²ºº:*•ÚÞÞN§Ó•••ååå¼¼¼Èdò–-[°NÊwp¾W‚-44tÙ²eS¦LIII!‰XÇé6&“ihhØÖÖVTT„Ç㱎ÓUMMMÒÒÒkÖ¬ À:Kgöïß¿cǬ³ð“É|òäÉÕ«Wsss³²²ÚÛÛ¹·Ááp ƒýiié‰'Nœ8ÑÜÜÜÊÊJ@Y Ö% ÔíÛ·ííí >|(//uœž¸sçŽhM–’’’²··¿víÖA:Ãd2¿~ýZ\\,))‰uÞûøñ£¿¿TTÔ·oß��d2ÙÜÜÜÄÄÄÐÐPWWWSSSIII\\ȧ®®®¶¶¶®®îÕ«WÅÅÅ111h£®®îéééáá1hÐ ŒŸo1!‚åÅ‹²²²êêê%%%Xgé¹9s戉‰UTT`¤Û´µµ'OžŒuŠ_»té�àôéÓXá±—/_NŸ>ÝùÚØØ:tèÕ«WÝm„Á`¤¦¦îܹ½®ÇÏ›7/77—1ÇK /_¾XXXÔÕÕ=xðÀÄÄë8=TQQ¡­­íääu–n355¥R©¯_¿Æ:È/Ðh4:^XX(*—awîÝ»w7n¼uë_¼xñŽ;x2È‘‘‘Ã`0/^|äÈUUÕÞ7‹-x=A‚ÐÐÐ`oo_YYyíÚ5Ñ-J��¡¡¡ííí¢2Ç+a^"‡@ðõõ---íó‰1ŒÓ§O›˜˜¤¥¥­^½úË—/.\àÕ‘—ñãÇ_½zõýû÷óæÍ‹ˆˆÐÒÒŠŠŠâIË‚ã%ñ]{{»½½ýíÛ·Eët:}РAïÞ½Cë8ݶxñ⨨¨¶¶6áßÒÒ¢«««¨¨˜——‡Ã‰êWè––ggg …2bĈˆˆˆ#F𯯷oßΜ9óãÇÞÞÞÇÝq&Qýφ H„¬ZµêöíÛ[·né¢�@¡PJKK½¼¼„¿Þ!2™L£Ñjkk±òk$iÆ ùùùqqqXg顚šSSS …²råÊçÏŸóµ(� :ôÙ³g3gÎüûï¿,XÐá>"Ö%ñ×BCC,XÐV± ’pwwÇ:H‰ÄÔj,«V­’““Ñ•üZ[[gÍšõöíÛ£Gž;wN0C>òòò «V­ºqㆫ««�zäX—@ÄG—/_Þµkׄ ÂÃÃEtŒ¥¤¤äÖ­[sçÎURRÂ:K‰V]"''·zõꜜœ´´4¬³tÛªU«ÒÓÓ÷îÝ»yófw}æÌ™yóæÅÄÄüõ×_îš'`]A¿Ü»wÏÓÓÓÀÀ ..N\\ë8½L§ÓEôŒW”hÕ%�€õëדH$‘iûçŸÂÂÂìííwîÜ)øÞ¹téÒ˜1c¶mÛöæÍÁè%X—@Äoß¾={¶¼¼<…BQTTÄ:Noµ··_¸pÁØØØÒÒë,='SѳSUU]ºtiZZZNNÖYºŠÁ`¬]»VIIéÂ… Xe ‰è…9¢8o=¬K â½ÊÊJ;;»¶¶¶ÄÄľ1e\\\ee¥¨Ÿ·‹Ž—TWWc¤|}} ‚ ™$&&nß¾}µ±¢§§çééI¡Pòòò0ŒÑ°. ˆÇ~üøaooÿåË—ÈÈH333¬ãðF`` ´´ô¢E‹°Ò+"w� ££ãâ⟟Ÿu–. %‘HK–,Á:ظq#�àòåËXéX—@ÄKt:ÝÅÅåÙ³g'NœprrÂ:o¼ÿþÞ½{®®®²²²Xgé999"‘(Zu �`ëÖ­ZZZMMMXù5&“ùðáÃÉ“' ÃbÈC† ÑÓÓ£P(XéÖD‚ô—ùèúÏ3…xÅÛÛ;))iÆ ëÖ­Ã: Ï1™LQ?ˆ�@DYYY$ê’oß¾•••µµµµ···µµ]¿~]NN®¶¶Vö÷øøñc]]ðÌhlffÃd2Eèj8X—�™çÏŸëëëÛÛÛ'%%˜››ûöM—_ï%Ž7.¬H –úúú/_¾444P©Ôööv:N&“åååUUUeddX›ýóÏ?çΛ={öñãÇ1LË[T*5""ÂÌÌLxv6½!œu N¿}ûö³gÏž?ž——WXXø³Ï111cccccã#FLœ8qĈB5lMM �@CCë ÿRWW�Ô×׋ÐÚݰ.666wîÜ4hPZZZ]]]jjêï¿ÿÞ‹ð_!ÇH~¦_½2wîÜyÿþýóçÏ333 :yâjjj††††††“'Ož>}ú¡C‡|||„jWÑKׯ_ÿþýû±cǰÂêêê---X§øW[[[pppJJJjj*:?)Ÿ0a˜1c  ¥¥E$ÅÄĈDbCCC]]Ý÷ïß?~üøþýûK—.………�äåå,X`ccC À=':ÞÖÖ†uŠnÂdc¡:{ölôŒå¬¬,‡ëׯ'%%©¨¨¨¨¨$''£›�¼½½ÅÄÄÐÛL&3$$d×®]L&3--mÀ€ èpÇÆ,�€Å‹ËÈÈ\¿~{3îŸ?>räHô󽇻£={ö þuøã/·ïûo�k×®•Ø¿ÛäÞ@$^+W®HKK£óxvøØ~òW“žž¾uëVÖW+A† 2sæÌuëÖ9räüùó/^ŒŠŠŠŽŽ8pà€¯¯¯µµõÀYƒm¿ýöÛ¾}ûŠŠŠ°~*<cii)//ßÔÔ„u>%//oÙ²eè¬6$ÉÉÉ)""âÍ›7 £+oooÏÌÌ<t裣#úÞSQQÙ¿MM ¿“w®¤¤�°uëVlc°ÌŸ?_BBëÝÓ—?a»¨²²RIIéâÅ‹D"188XEE¥±±QOO/)))))I__Ý �A£ÑÐÛaaaÛ¶mCeddt÷îÝœœîY��h›C† áÞŒ»Gccã'NP©TV ÜIJJ†‡‡Óéôüåöâ¨Ksssåå廨&÷"ñ èëëS(ô±Ÿ=¶W$4- �|FÄÄÄdçηoßæxw¢¡¡!66våÊ•RRRh2qâD …ÒÅÝŒ0hiiÉÊÊ ðôô´±±:t¨ŒŒ kñ3ATTT† fmm½fÍšàààÌÌÌÎÿ”„MMMMAAÁëׯŸ={öøñã>TUUuý¿˜W>}úäææ†Ãá±¶¶ŽŽŽfÿïúúú}ûö¡säàñøuëÖõ²Á^RVV¶¶¶Æ0� ƒÁÐÒÒ3f ÖAº§Ï~Îv‹©©©•••§§§¥¥åÌ™3™L&omm¥R©Ý�ÐÞÞκ­¯¯___þˆÇãñx<‚ è8?ÇÆ,��´Mqqqî͸{$_Ѹ;ºxñ¢™™™±±quu5÷¿Ü¾Cu º_aÝùË6¹7‰W€H$¢½wòLûd]ÒÞÞ„„ÖÐÐØµkWiiiod0YYYëׯG÷èÇÏÍÍåUZ~øôéÓÉ“'mllX%‡ÓÐÐ055uvv^¸pá’%K¼¼¼\]]íììÌÍÍÕÔÔX#gx<~öìÙ§Nª­­Åúyp¢Ñh©©©ûöísrr>|øÏެ!2xðà3flÚ´)66¶±±‘‘ètúÉ“'I$‚ ÎÎÎèñA^a0IIIèuéd2ùöíÛ<l¼[æÏŸ/&&VQQU�–gÏž�vïÞuî郟³=°wï^€^áÂ&“‰^[E¡PôôôÐm8öÖ©©©ŽŽŽèW ##£ÄÄDöoNîÀ��h›†††Ü›q÷hll|êÔ©ÖÖVÖ6Ü1™L6~üø«W¯rÿØ•í;ÌÉ}›}¡ó6;Ü@ø_ÇK8K$ËÊÊ:zÍDÕÛ·oMMM�ZZZaaaÜÅto444øøø ;ûÍ›7cû–[{{{LLŒ­­-ºÃ÷òòò÷÷ÏÌÌdËuˆF£eddœ<yrÖ¬Yèå!‚888$$$`>>ÔÜÜìïï?yòd<Ï*žÆŽ;wîÜ 6:tèĉÿý÷¹sçþüóO__ßeË–YZZ²¯øcbb²oß¾ââbÞûñãǤI“��ÚÚÚOŸ>åmã, #<<\UUA­[·òö-ÝE©©©�€½{÷ ¾k ,ÀápèIÄ"Ö%L&“ùìÙ3sss&“©­­]UUÅd2Èd2™LNLLD·áÞ[‡„„x{{3™ÌŒŒ }}}ö3~V—,Z´HZZúÚµkÜ›q÷øìÙ3cccôÐ)zO‡�Æ‡Ææø±+Ûw˜“ûv×3po ̯�ËåË—¥¥¥]]]Y£5Ü]·n‰DêðEEaaaALLÌßߟÇ#ÊËË.\ˆ ˆ¶¶vNNŸzéƒmhhˆ–#qqq=~h4Ú­[·–,Y"--~Sàmà.JOOwvvFÏý”––vqq‰ˆˆÈÏÏïb©TUUµjÕ*ômoiiyóæMž¼7 Ñ¿&oooÔ UUU666��++«_V™ü0räH))©’’ÁwÍòüùsA,X€a†žé#Ÿ°"¡ÏìÏzLø_›7o²Ærú0ƒñÇ��†úéÓ'ô#++‹ÃánÞ¼)€î:ññãÇÑ£G�deeÚÚÚxÕrmmíŸþ©¢¢‚¾ùùù¼jù—ž<ybmm �svvNKKëͰ z$nÕªUèX—¡¡aBBBoâ•——«©©‰‹‹_¹r¥7ít ƒÁ@WXœ6mZKK‹ÀúEeggãp¸ &þôTcc£„„ÄÇ1 оŸèK„¯ÌoBþ  ß2ùщ___�€µµ5ë)x÷î‚‚‘HìåN®7Î;G$ñx¼ŸŸŸŽ+566nÞ¼YLLLBB"$$„]°ûñãÇš5k!‰ëÖ­ãí9 ‡B§®777ïÙ·ÿ††ccc<ïÞ=fë"tÕ:Áw½uëV�ÀêÿkïÌ£¢¸²?~«Z@ÅF‘EŠëqûiƒQƒq’ *"¸DcŒÆ£ñèhq¢&¸%jKtœ—ÑÁ#n b„'9È€"Dèîúýñ’:eUuÑ@wW+÷óGN¥ûÕ½÷ÝÂz·_½zßwßµ¼ë–––W^y�:dyïÇªÇ ALÎ�`Ò¤I–_ qçÎ///¥RYTTda×Z­–üz ¹yó¦¹Ý•””ôíÛ�>øàóåùÆä%”ÈÈHó­W­­­}÷Ýwår¹Z­>{öl{Oûí·`ïÞ½æˆÍf̘�"+êÌ„N§›>}:�,[¶Ì’ïméõú?þñ�°dÉ‹95-X— Hâ?ÿù]PPPCCƒ$”””(•ÊÀÀÀ¦¦&‹9ÕétS¦L€7ÞxÃbSúMMM“'O€¸¸8s K™™™NNN*•Š,Õ77/^$‹IwïÞmüYäqÆôéÓÍX›<zôÈËËËÝݽ±±Ñ®›ššÈóµiÓ¦YfÝwyyùˆ#�`ñâÅ’/Áî0X— H:éŒú��©IDATb„ 666?üðƒ„1ìÙ³�6mÚd1+V¬�€èèh ß©µZmtt4�¬X±Â´–/_¾¬P(zöìYPP`ZË"444 :”¢¨;vyʤI“”Jåýû÷ÍX›üãÿ�€ÄÄDË»ÖjµóæÍ�OOϬ¬,ó9ÒëõûÛßzôèacc“˜˜øü%4Ö%"øºŠIìX í lãÆd‘å]›«½"/^€åË—K†N§8p Z­¶ÌœÍÉ“'`Ê”)’¬@ÔëõE¥§§›Êfqq±³³³‹‹‹eÖ,³ùõ×_‡ �Ƭ_.++“Éd±±±æ« t:··wÿþý¥ àøñãd›éÈÈHs<FÌËËëß¿?Y!'É:Ób¥7ЮÀ V—À³Ðí ¬GdUIºcªÜšÊ»•+“ÉL¾/E ¿_>lnGõõõ½{÷vww—ê¹MÓ÷ïßïÕ«—»»»I]µ´´:88HõÒõÇ{öì©V«ÿ÷¿ÿ‰·Ü¹s'�XÉ0¹fÍ�())‘*€ªªª Me&Ož|æÌ™Î?ÝÓétÇŽ=z4yã}íÚµ/†Z‚•Þ@»;·±:XçN¬êŠ0èõz——_~Yê@hš¦=zdgg÷Ö[o™ÛQBB�0zLRqôèQ�ؼysçM%&&À_|ÑySæÊ•+2™,**J¼Y\\œ\.·’‘òüùó�pðàAi謬œ;w.©N4Í’%K222Ú»æééÓ§GŽ™;w®ƒƒ�8::®X±¢“Û4[Öxµ<-7àÉË‘íííwîÜIÓt¯^½***rrrÈ|fuuu¯^½hãTîŽ?îèè'X—0~kjj @ êÖÖV??¿óçÏ3Í8Óm:eà«Óµ)tG¶B�WWWòœ¸ººÚÕÕõáÇüLrŠ#œe–¤;HN÷Ì Û,ç+~Nfÿ%ÐBâ‚|ÖÀ;w�`íÚµRòãÆÓh4fu¡ÕjûôédV/Æ Óé|}}=<<:ùÔ¿©©ÉÙÙ9((Hª]1fΜ)“ÉŠ‹‹EÚŒ;VÂG'~þùg�ذaƒÔÐ4M×ÕÕmÙ²åø¹eÉåòÁƒÏŸ??11ñرcyyy·nÝ*++«¨¨¨¬¬,**ÊÍÍMMMݰaÜ9sÆOÎ’ÉdãÇß»w¯j t¬Khš§å<y9Bqq1©?¦Nš““óæ›o®^½:444??Ê”)´q*w HOO?}ú´`]ÂöG”u÷íÛG¶£e·d·é”¿Ûz›Bwð»´ÞÂ… ‰ÎB||ü¢E‹3ÙáÀ؃:Ç/?HcæK8®Ùf9_ñsÂ`(`æ/ä»°ÈïÅ#GŽHÈoDGGÛÚÚšuu^vv6�lß¾Ý|.ŒgÆ �Ðɇ/‡&ÿ.LU‡!ªdÃkCŒ3†Ñà”œªª*�غu«Ô<C]]ÝgŸ}È(r‹@QT``àÂ… “’’¬AÇL`]BÓ<-7àÉËÅÇÇ;99‘? š¦Ö¯_ïëë«Õj}||¢££ãããiãTîøúp ¿ùùù‘‘‘OŸ>Õh4)))œ–ìã62ð½·)t¿Kë»»»×ÖÖº¹¹ýøã‚™ìp`‚u ³_5ÿµ×5û€ó•ÈáÌùK …Äù.¬¢ÙqôèQ©ùwÞy‡¢(n·ÊgóæÍ�`%ªDA­“¯„DFFªT*³&ÍxBBB¼½½E„‡‡÷ìÙÓbñˆsóæM�ضm›ÔäÑ£G………ééé_}õÕgŸ}¶~ýú?üðÏþó¶mÛ<xòäÉŸ~úéùÒ¯î0Vtß”¶–ðäåìíí òòòÈH“ššªR©È,ýÆ€Ô üQ¯ýæï‘‘––&X—püŽ5jåÊ•äü¬d Èã”Apn@\èŽÝ2<<|ôèÑ'N4”FNq`|`‚»;HAý<ñœˆˆÏ—pæü%ÐB₆º -$æ¿þõ¯RòÓ§Owrr2«‹ØØX¹\.ù#BCC�¼÷Þ{1Ò§OŸ±cÇš*¤N²råJ�Q²$¯g[ÉÏúääd�à?ÚF¬+ºoJ™"ck¿qäå-Zdoo¿xñb2ÒTTTÈårò’“5Gü‰¯ý–œœ¬R©bbbëŽ_²5gRR§%[@Χ |u:NßÅ5I9EÞx4fÒÂøÀÄëN‚úyâ99àç„0ç/´Îº¤¾¾^&“-\¸Pê@~cÀ€!!!fu1sæL{{{³ºh¶¶¶ÙÈäÉ“'�`èªåÙµk�ˆ(“RÀž:Ñ4=gÎÁUqˆµaE÷MëÁJ†“ÖÖÖO?ý444Ôä?øºˆ:]»è 9 öòò²†©à_~ù�V®\iV/³g϶±±±†þÒ4ýøñc�X¼xq‡-466v~ÆÅ„9r„¢¨+W®jðøñãîÝ»3Æ’Q RSSãèè8a©AŒBˆµ¢T*SRRÎ;G^*3EÅÄÄ÷'BÉÉœ9sÊËËÉBiÙ¿?�¼þúëfõ ÕjoݺeV/FRVV�žžž¶`kkKQ©N¬òvyUU‡ØØØ‹/ž={Ö’ñÙºu+ÑS”6 ÄX¤.Œ±UUUr¹|ذaÒN!Ü¿_©TŽ=ÚÜŽÈš! ãØlÛ¶ �rrr:c$00pРA¦ ©“¼ýöÛEÕÕÕ‰´yðàZ­îÙ³§åµiòóó Å!C¤ �i/8_‚ ]õë×çççïÞ½[ªhšž?þ“'O>ýôSsûš0a‚Z­þúë¯ÍíÈ>ܽ{w²5g‡>|xqqqMM©¢ê04MŸ={vèСÎÎÎ"Ízôè±{÷ªY³féõz‹…ÇðäÉ“™3gÚÙÙ}óÍ7–÷Žt ¬K¤ ±zõêÀÀÀ>øà_ÿú—$lÙ²%--méÒ¥cÇŽ5·/{{û9sæ\»víÂ… æö%NFFFQQÑ»ï¾ÛÉg²ÑÑÑZ­–,‡—–ï¿ÿþîÝ»‘‘‘m¶ŒŠŠZºtijjêìÙ³-\šÔÖÖŽ5ª´´ôðáÃÌvä9@ê +E\F® æí¹è²xÏE,@ii©›››««ëíÛ·-ìz÷îÝE 2„Ù™ÆÜTVVvïÞÝÏÏý"·…illôóóstt¬­­í¤)½^߯_?²Ibë0#GŽT©Täý¸6Ñét¯½ö�Lž<Ù$"AÆPVV@QÔž={,ã1x§†‘‘¤ ŽpÆtYò´˜°.gßR¦ŸÝê^°¾'jµzÿþýí…¸zõª½½½ƒƒÃwß}g:Žìf1xð` ©ä¡Õ¼yó,é”ÍìÙ³à믿6‰5²U´´ï{“7„Û¥i Õj—,Y�×®]3_l„C‡)•J²ãò|ÑåÆW#áaüªKa’.›;o&¼j†NäáuùòeãIEQQ‘F£‘ÉdË—/7÷OØÇGDD�@PPÙ±×’èõú3f�ÀªU«,욦éÕ«WÀ´iÓLhsâĉ�pàÀÚ4žëׯÛÚÚ†„„´WmަéÇ;88Pµxñb3)<ÿüóÏDwF£ÑH%¹Œt’.7¾ ’žžîîîîîîNôhø¹ø¿ŒÛT¤kSmœ#,É:Nl´P\›ÞÛ †Ó€¯2ȇÝkœŠÛaºoŒrž!)Ä\5~_DŽ¿º|ù²³³3ý<PYYIyøûûŸ:uÊ.ZZZ¶lÙ¢R©(ŠZµj•Åßphnn>|8�,_¾Übï"étºùóç@DDD†pêêꂃƒe2YZZš ÍCaa¡Z­¶µµ-))阅ÊÊÊqãÆ‘ÂùË_=zdÂØÈîˆ666ï¿ÿ¾ø‹Bˆ5ƒu MÓ´¯¯/ÌcT¦Úüåݦ"]›zxlk™@`IÖñcã ŵé½Í`8 ø*ƒüxø)2dCq;L÷QΗBd·KGSÖð ò퀋‹‹•¼˜j$Ÿ|ò‰B¡�€>}úìÙ³ÇTÃvCCömÛ4 �„„„äææšÄl‡illœ:u*�¼üòËÕÕÕævWUU5räH�7‡œÍǽ¼¼är¹%^½zÕÕÕÕÑÑñÒ¥K4uöìÙ°°0�Éd¯¿þú¾}ûØ7´vQUUµcÇRwÊd²7ÞxãæÍ› ‘¬Khš¦år9QncïÎÎiÃÚT¤kSm#,É:~l|¡¸6½· §_ÓŽ?E†¬±s(n‡Ýý6•óÄ¥ÙÇÐ9ÿê9¢®®nݺuݺu�''§„„„«W¯vLé·¥¥%##ƒÌÿ€»»ûW_}eVÑ`ãÑétñññE988ìÚµËLQiµÚ/¿üÒÅÅE&“}ôÑG曞¹{÷nhh(�ÄÄĘ[é^¯×oß¾]&“9::ŠlðÚ^›ÙÙÙQQQ¤,–ÉdÓ§O_·nÝÉ“'‰¬‡!Z[[ =ºdÉ’—^z‰H@(•ÊeË–‘­ÞççõNjZ|}}‰r›¯¯/ù„?Æt@*O\xr}œyNl|¡¸6½ §=¯2ȇÝqkìiÇå<)Ä v©º„P[[»sçÎ’‰;;»¨¨¨mÛ¶]¸pAd ¸^¯ÿå—_Μ9³}ûöððp;;;R2†‡‡ïرÃJö€g“››Û·o_�ðöö>uê” «“ÖÖÖ¤¤¤   �èÛ·¯¦ˆêëëÉ¢Ú>}ú$%%™©ÒÊÉÉ!£Fº{÷®Éí×ÖÖ&%%Íœ9ÓÕÕ•™¡¤(ÊÓÓsäÈ‘ãÆ õÕWGÜ»woöDf@@ÀòåËÏž=k…iH‡y¾ï¤¦"55ÕÍÍÍÍÍy^ËcÚ+•GŽEôð€'×ÇnÃ/צ÷6ƒá4`à« òãawDÜ;‡ÆØ •¯œ'"…ØaÃ.X—0”””lÚ´iøðáäoŒ'¼½½ÃÂÂFõÿ÷&L8p`Ÿ>}È]‚R©œ6mZbb¢  ˜ƒ¦¦¦Í›7«Õjø}¯¹²²²Î¼{÷îÇLÊ;;»µk×Zr%MNNNÏž=ÀÓÓóÀ&¡333_yå�prrÚ¾}»:UZZzüøñ>ú(666<<<00ÐÇÇG£Ñxxxøùù 6ìÕW_]¸páÖ­[¿ÿþ{ ßýFÌ E·õ$bnÈC©£@.:îÆ¹¹¹÷îÝ«¨¨¨¨¨¨¯¯úôikk«^¯ïÑ£‡‹‹‹‹‹Kpp°¿¿ÿþýÉ3þç…úúúƒîر£¼¼�‚ƒƒg̘fŒŠÍÝ»wÿýïçææ^¾|ùÊ•+�àããóþûï/X°€”–äñãÇ;wîܲe˯¿þêää´zõꈈˆ°°0vei<ÿýï=š””ôÓO?ÙÚÚ®ZµjíÚµä1‚X�¥ë‘´´´ìììo¿ý¶²²’|âîîîãããééÙ¯_?Åï466ÖÕÕÕÔÔ”——_¿~½¥¥…46lؘ1cf̘!yYÖÐД”´wïÞ¢¢"�ppp˜5kÖàÁƒÃÂÂBCCEª%NW\\|ëÖ­ìììÜÜ\¢tØ­[·wÞy‡YÎ… GDA�€’’’~øáúõë7nÜ(///--Õétœ6vvv^^^þþþƒ ž:u*YákUž9s&##ãÚµkLÔjµ§§§‡‡‡­­­Mmmm]]]}}ýíÛ·IŠ¢^zé¥ñãÇÿéO5jTǦ[¤“`]‚ "LMMMkkkKKKKKK·nÝ\\\,ÿŒ¦3477ççç_¿~½´´ôÎ;<hnnnmmÕjµä1œ«««ŸŸŸ¿¿@@@DDÑß@ ÁºAAkõ„�:9]ÙÉÓ7mÚ¤P(L>e*m§¬ß¯™ÒŽ ‚tœ/èôÊÓNžîææVPPàååÕa ‚˜ªS^–k1wLÚqÝ1‚ ˆõ€wd�©ëŽ‹lS’DÕù¾ð-´×¦‘í%/G$�AÄ Áç8¿±téR¥R¹aÃò¿ÙÙÙÆÕÕõäÉ“LŠ¢”J%Ñø€'N899Í;—iÀ?‹¢¨eË–‘½§Ö¯_ïææÆyp@þ—ù/ÓøÌ™3LË÷Þ{¯[·n»víš?¾R©Ü´i“ )Æ…1"<˜lÊÎùŠùD°wlü� ¥Žs¢`2;ERDQT@@€^¯�­Vëï•%ØžŸFÁ´“¿ùæ¢ÿÇ|"xÀ\#‘| ^>A×ø Aä,³}›•F+º‰ËÅñÏ–]›jv *×�)))………r¹œ¨ÕjC¦ÚÕ)ZH x»£ öŽãBä/Š:þ‰Ækï‘ÅÅÅ!â}ûö1ÂP{cT™???²5>ÿ+Ák$’O%Hþ‚ €wFš6NÑ͹8þYÀ’ kSÍDåúØAr¢å›2²S |-@þð)Ø;Ž Á±–Ÿ:þ‰Ækï‘åççGFF>}úT£Ñ¤¤¤joŒÊ H ä€LÌpLˆˆ_ASü\!‚tqð9Îop¦ÓýýýSRR´Z-H�`óæÍ.\ÈËË£_Я_¿¬¬¬ÌÌL‘³�ÀÆÆ†ÄÄÄ\ºtÉÉÉéüùó†Â`{{{geeegg÷ëפ¡É…BqïÞ=ã;Å´ÿ~f KAOç¸à@à§Ž"?™†l’ :´¦¦fݺuÎÎΑ‘‘†Ú ¦Ñ}ûö%™OœÉUìfÌ5É'ß/ß”`®Aº:RFVð~ÂvL.NPí„Ôì‹H ¶'tX¦Ž¯hÌéüv� üÔñÚ«½GÓô� ))I¤½‘*ƒä ))I¥RÍš5‹™äøøãííí—,Y"˜s‘|òýòM æ A¤‹ƒo Ï%Z­vëÖ­ÉÉÉr¹Ü„–SRRÖ¬YC$BA c#u�Ò”Jå!CÎ;gÚ¢„¢(•Jµoß>ÚDAŒçKA±pÝ+‚ ‚ ÖÖ%‚ ‚X X—¤]qZx×NÜ$Ô¬X[zQbA®Ö%íÀ$Ž.ÄT 4Ç…˜7o^]]ÝÌ™3›››MhöóÏ?¿}û6Y EvÁ�…BeBG‚ ’ƒïã´“¬4‚nlijaªD™#áõõõÝ»wojj²³³3¡ÙššFnúĉ>$ÇÕÕÕnnn&t„ "98_½{÷¾wï^nn.EQ)))÷ïßïÝ»7ùŠ£-ÇüÂT¹ã4€ÚÚZµZýàÁ�¸ÿ¾Z­®­­å+Àñ¥é8{LJ# hHA¢(~HârƒâY2¤]'’Uq ¿6íøŸ‹èç±ÏŠurr:qâÇŽ!̓&$$ðí^ˆ?þ˜¢¨þóŸE¥¦¦2¦8×…ïKPáO0!�P]]mgg×½{wÒÒÅÅÅÖÖ¶ººÚP¯Až?$ÛÑÍj˜:ujNNΛo¾¹zõêÐÐÐüüü)S¦Ð¢¢t‚*wœÆ„… &$$Ð4¿hÑ"úÙmF8ö…�¡­Eižî§Q@A~HârƒâY2¤]g¨½`_ŒÿüVD?}Ò àØ¼š‡Z³f )vðlN:¥Ñh:Ì|ȹ.|_‚ †�ñññl§~ø!þ+FäEïhtBBÂúõë}}}µZ­Ott4¹õƒaQ:A•;A-½ââbww÷ÚÚZ77·ü‘cQ€ã×%l7AÝ;N/8¢€" ‚üÄåųdH»ÎP{c4üÚ[—ˆèç±Ï"Bzvvv;‚WÓÏϯ¾¾žc„<û6ëÖ­#Ÿs® ß—¸@#'Ô¢¢¢=z°Owuu-..6ÔkAç¬KèÔÔT•JõÉ'ŸÐ4½qãF� ú´üQý û‹/¾hnnfŒˆŒ©ááá£Gž8q¢HK…BQQQAޝ_¿ž––Æ4°··/((ÈË˹µZí˜1c’““iš LKKc~¦sNá„$ÞX<KüsÅÛ‹ô…9`gƒà|‰` œ³222222 À±#x5333§M›Æž1 žÍôéÓõzý´iÓ8Ÿ³¯ ß—¯¯/ Ì××—ÿ€]­Ê‚ Ès ÞÔ芊 ¹\NBr\^^N‹ƨÜ1 #==]¤%[Â/ð&¢{Ç@~¦3¢€â ‚œÄ‹gÉv¡öÆhøê3ÔÞ˜ø`öìÙ*•êÛo¿å´1t58°téR¶~ð ­­­o½õVCCCLL Ç/ûºð}µW Q¡PTUU‘ãÊÊJfúAäÅ�_A¬S½©ô¼ñ´`Á‚#GŽ´´´�€B¡˜3gÑUFy1xAnÖ"Î S— ‚¼ØàÍAAk÷/AAÄZÀºAAkë3Ò¤pºBA‹u "%7nÜðõõ€/¿üÒÕÕÕÓÓ399Yê AÉÀº‘’ï¾ûnÒ¤I�PZZZVVö÷¿ÿì‚ ‚tM°.xV¦Ž/g¤ÖcáĉNNNsçÎôõðáÀ€�²q§V«õ÷÷ÏÊÊ‚gá ‰ÞqDà8˜OºÏA~N³ÄÏ;wî\DD�|þùçÎÎÎ …‚‘÷CAº"Rnêf5�K¦Ž/g¤ÖcaÀ€ééé§OŸ6”Þ¸¸¸3gÎÐ4½oß¾#F0Ÿ3‚p†Dï8"pÌ-ÝÇ“fmEÊω`–Øây=R©TÌ·ööö™™™‚½CAºX—Ðô³2u|8#µÖ …‚|k¨.ÉÏÏŒŒ|úô©F£!ª1A8C¢w8æ–îãÇI³ê~N³ÄÏ;}úô„ ãz½>;;[DAyáÁç8¿accCüýýSRR´Z-yÔ�AAAû÷ï';¼½½³²²È ʷЯ_¿¬¬¬ÌÌLC¾†ZSS³nÝ:ggçÈÈH�ؼyó… òòòhš€!C†lÙ²%66V.—Ï›7ïèÑ£aaa�séÒ%''§óçÏóÍr¾åw„ 2888$$äµ×^4hPPPxc6œ8Ùðs"˜%ö'Ìâ�HLLlnnniiihh0”7AäÅGêÂÈ*`ç/×.­5𦓓“U*ULL –‘#š&IIIä9‚p"R‚Àã÷Ì#ÝÇ‹¨îñs"˜%¶xžÏ7ÈW›6mrppÐh4ÇŽãw Aé"à>ô Õj·nÝšœœ\PP —Ë¥§mP<A± ܉zÄ(•Ê!C†œ;w®3E ç­³Ž÷XL ‚ –¿"‚ b-àºWAA¬¬KA±°.AAÄZø¦Ò{æ9����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/contributors.txt���������������������������������������������������������������������0000664�0001750�0001750�00000003354�12605311413�013544� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tomas Abrahamsson Nicolas Adiba Manuel Durán Aguete Fabian Alenius Jason Andersson Per Andersson Joe Armstrong Michael Arnoldus Oleg Avdeev Tuncer Ayaz Stu Bailey Kuzma Bartosz Eric Baur Johan Bevemyr Martin Björklund Dominique Boucher Adam Bozanich Richard Bucker Yinso Chen Gaspar Chilingarov Mats Cronqvist Anders Dahlin Robert David Willem de Jong François de Metz Kaloyan Dimitrov dnz@bk.ru doccarcass Colm Dougan Hans-Christian Esperer Daniel Fabian Christopher Faulet John Fessenden Michael Fig Bruce Fitzsimmons Magnus Fröberg Olivier Girondel Sergei Golovan Luke Gorrie Igor Goryachev Joakim Grebenö Paul Hampson Per Hedeland Christian Hennig Sean Hinde hun@n-dimensional.de Wes James jcortner@cvol.net joe_e_e Dimitriy Kargapolov Mikael Karlsson Bengt Kleberg Petter Larsson James Lee Ahti Legonkov Peter Lemenkov Michael Leonhard Eric Liang Fredrik Linder Fabian Linzberger Daniel Luna Paul Mahon Davide Marquês Brady McCary Tom McNulty Chandru Mullaparthi Andrei Neculau Chris Newcombe Hans Ulrich Niedermann Julian Noble Joseph Wayne Norton Anders Nygren Thomas O'Dowd Jimmy Olgeni Lennart Ostman Karel Ostrovsky Erik Pearson Jean-Sébastien Pédron Karolis Petrauskas Phanikar.K Yurii Rashkovskii Praveen Ray Matthew Reilly Mickael Remond Bruno Rijsman Bill Robertsson Jouni Ryno Yariv Sadan Kostis Sagonas Rob Schmersel Carsten Schultz Yariv Sedan Tomas Selander Vance Shipley Alexander Simonov Michael Slaski Garret Smith Leon Smith Hal Snyder Andrei Soroker Matt Stancliff Sebastian Stroll Taavi Talvik Brian Templeton Nicolas Thauvin Fredrik Thulin Torbjörn Törnqvist Tjeerd van der Laan Pablo Vieytes Steve Vinoski Lev Walkin wde John Webb Johannes Weißl David Welton Ulf Wiger Claes Wikström Dan Willemsen Haobu Yu Liu Yubao Kalle Zetterlund ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/arg.yaws�����������������������������������������������������������������������������0000664�0001750�0001750�00000006210�12605311413�011716� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> out(A) -> {ssi, "TAB.inc", "%%",[{"arg", "choosen"}]}. </erl> <div id="entry"> <h2> The Arg </h2> <p>This page displays the Arg #arg structure supplied to the out/1 function. </p> <p> The #arg structure is a very important datastructure for the yaws programmer. It is the main mechanism whereby the server can pass data to the web application. There are several data items which are of interest to the webapplication, such as which headers were sent from the client, etc. The #arg recored is defined in <tt>yaws_api.hrl</tt> and is defined as: </p> <div class="box"> <pre> -record(arg, { clisock, %% the socket leading to the peer client client_ip_port, %% {Ip, Port} for the client headers, %% headers req, %% request orig_req, %% original request clidata, %% The client data (as a binary in POST requests) server_path, %% The normalized server path querydata, %% Was the URL on the form of ...?query (GET reqs) appmoddata, %% the remainder of the path leading up to the query docroot, %% where's the data fullpath, %% full deep path to yaws file cont, %% Continuation for chunked multipart uploads state, %% State for use by users of the out/1 callback pid, %% pid of the yaws worker process opaque, %% useful to pass static data appmod_prepath, %% path in front of: &lt;appmod&gt;&lt;appmoddata&gt; pathinfo %% Set to 'd/e' when calling c.yaws for the request %% http://some.host/a/b/c.yaws/d/e }). </pre> </div> <p> As we have seen is several previous examples, the <tt> out/1</tt> function defined in .yaws files, gets invoked with a single argument which is a #arg{} record, fitting the specific HTTP request being served. </p> <p> The code to display the #arg{} record is in defined in file <a href="code.yaws?file=/arg2.yaws">arg2.yaws</a> and is invoked at <a href="arg2.yaws">arg2.yaws</a> </p> <erl> out(A) -> Peer = A#arg.client_ip_port, Req = A#arg.req, H = yaws_api:reformat_header(A#arg.headers), {ehtml, [{h5,[], "The headers passed to us were:"}, {hr,[],[]}, {ol, [],lists:map(fun(S) -> {li,[], {p,[],S}} end,H)}, {h5, [], "The request"}, {ul,[], [{li,[], f("method: ~s", [Req#http_request.method])}, {li,[], f("path: ~p", [Req#http_request.path])}, {li,[], f("version: ~p", [Req#http_request.version])}]}, {hr,[],[]}, {h5, [], "Other items"}, {ul,[], [{li, [], f("Peer: ~p", [Peer])}, {li,[], f("docroot: ~s", [A#arg.docroot])}, {li,[], f("fullpath: ~s", [A#arg.fullpath])}]}, {hr,[],[]}, {h5, [], "Parsed query data"}, {pre,[], f("~p", [yaws_api:parse_query(A)])}, {hr,[],[]}, {h5,[], "Parsed POST data "}, {pre,[], f("~p", [yaws_api:parse_post(A)])}]}. </erl> </div> <erl> out(A) -> {ssi, "END2",[],[]}. </erl> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/session1.yaws������������������������������������������������������������������������0000664�0001750�0001750�00000003416�12605311413�012716� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> -record(myopaque, {udata, times = 0, foobar}). out(A) -> H = A#arg.headers, C = H#headers.cookie, case yaws_api:find_cookie_val("baz", C) of [] -> M = #myopaque{}, Cookie = yaws_api:new_cookie_session(M), Data = {ehtml, {html,[], ["I just set your cookie to ", Cookie, "Click ", {a, [{href,"session1.yaws"}], " here "}, "to revisit"]}}, CO = yaws_api:set_cookie("baz",Cookie,[{path,"/"}]), [Data, CO]; Cookie -> case yaws_api:cookieval_to_opaque(Cookie) of {ok, OP} -> OP2 = OP#myopaque{times = OP#myopaque.times + 1}, yaws_api:replace_cookie_session(Cookie, OP2), Data = {ehtml, {html,[], [ "Click ", {a, [{href,"session1.yaws"}], " here "}, "to revisit", {p, [], f("You have been here ~p times", [OP2#myopaque.times])}, {p, [], f("Your cookie is ~s", [Cookie])}]}}, Data; {error, no_session} -> new_session() end end. new_session() -> M = #myopaque{}, Cookie = yaws_api:new_cookie_session(M), Data = {ehtml, {html,[], ["I just set your cookie to ", Cookie, "Click ", {a, [{href,"session1.yaws"}], " here "}, "to revisit"]}}, CO = yaws_api:set_cookie("baz",Cookie,[{path,"/"}]), [Data, CO]. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/code/��������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312016�011233� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/code/Makefile.in���������������������������������������������������������������������0000664�0001750�0001750�00000035616�12605311446�013241� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = www/code DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = myappmod.erl EXTRA_DIST = $(MODULES) EBIN_DIR = @top_builddir@/examples/ebin EBIN_FILES = $(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign www/code/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign www/code/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: ������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/code/myappmod.erl��������������������������������������������������������������������0000664�0001750�0001750�00000001000�12605311413�013474� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-module(myappmod). -author('klacke@bluetail.com'). -include("../../include/yaws_api.hrl"). -compile(export_all). box(Str) -> {'div',[{class,"box"}], {pre,[],Str}}. out(A) -> {ehtml, [{p,[], box(io_lib:format("A#arg.appmoddata = ~p~n" "A#arg.appmod_prepath = ~p~n" "A#arg.querydata = ~p~n", [A#arg.appmoddata, A#arg.appmod_prepath, A#arg.querydata]))}]}. yaws-2.0.2/www/code/Makefile������������������������������������������������������������������������0000664�0001750�0001750�00000036464�12605311455�012636� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # www/code/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/yaws pkgincludedir = $(includedir)/yaws pkglibdir = $(libdir)/yaws pkglibexecdir = $(libexecdir)/yaws 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 = x86_64-unknown-linux-gnu host_triplet = x86_64-unknown-linux-gnu target_triplet = x86_64-unknown-linux-gnu subdir = www/code DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} /home/klacke/yaws/ac-aux/missing aclocal-1.14 AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 0 APPDEPS = AR = ar AUTOCONF = ${SHELL} /home/klacke/yaws/ac-aux/missing autoconf AUTOHEADER = ${SHELL} /home/klacke/yaws/ac-aux/missing autoheader AUTOMAKE = ${SHELL} /home/klacke/yaws/ac-aux/missing automake-1.14 AWK = gawk CADAVER = CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -Werror -Wall -O3 CONFIG_STATUS_DEPENDENCIES = $(top_srcdir)/vsn.mk $(top_srcdir)/applications/yapp/vsn.mk CPP = gcc -E CPPFLAGS = CURL = curl CYGPATH_W = echo DEFAULT_CHARSET = undefined DEFS = -DPACKAGE_NAME=\"yaws\" -DPACKAGE_TARNAME=\"yaws\" -DPACKAGE_VERSION=\"2.0.2\" -DPACKAGE_STRING=\"yaws\ 2.0.2\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DCPU_VENDOR_OS=\"x86_64-unknown-linux-gnu\" -DPACKAGE=\"yaws\" -DVERSION=\"2.0.2\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_SECURITY_PAM_APPL_H=1 -DHAVE_LIBPAM=1 DEPDIR = .deps DIALYZER = /usr/local/bin/dialyzer DLLTOOL = false DSYMUTIL = DUMPBIN = DVILATEX = latex DVIPS = dvips ECHO_C = ECHO_N = -n ECHO_T = EGREP = /bin/grep -E EPAM_CFLAGS = -I/usr/include/security EPSTOPDF = epstopdf ERL = /usr/local/bin/erl ERLANG_ERTS_DIR = /usr/local/lib/erlang/erts-6.2 ERLANG_ERTS_VER = 6.2 ERLANG_INSTALL_LIB_DIR = ${prefix}/lib ERLANG_INSTALL_LIB_DIR_yapp = ${ERLANG_INSTALL_LIB_DIR}/yapp-${YAPP_VSN} ERLANG_INSTALL_LIB_DIR_yaws = ${ERLANG_INSTALL_LIB_DIR}/yaws-${YAWS_VSN} ERLANG_LIB_DIR = /usr/local/lib/erlang/lib ERLANG_LIB_DIR_compiler = /usr/local/lib/erlang/lib/compiler-5.0.2 ERLANG_LIB_DIR_crypto = /usr/local/lib/erlang/lib/crypto-3.4.1 ERLANG_LIB_DIR_erlsom = not found ERLANG_LIB_DIR_erts = /usr/local/lib/erlang/lib/erts-6.2 ERLANG_LIB_DIR_eunit = /usr/local/lib/erlang/lib/eunit-2.2.8 ERLANG_LIB_DIR_inets = /usr/local/lib/erlang/lib/inets-5.10.3 ERLANG_LIB_DIR_kernel = /usr/local/lib/erlang/lib/kernel-3.0.3 ERLANG_LIB_DIR_mnesia = /usr/local/lib/erlang/lib/mnesia-4.12.3 ERLANG_LIB_DIR_public_key = /usr/local/lib/erlang/lib/public_key-0.22.1 ERLANG_LIB_DIR_sasl = /usr/local/lib/erlang/lib/sasl-2.4.1 ERLANG_LIB_DIR_ssl = /usr/local/lib/erlang/lib/ssl-5.3.6 ERLANG_LIB_DIR_stdlib = /usr/local/lib/erlang/lib/stdlib-2.2 ERLANG_LIB_DIR_xmerl = /usr/local/lib/erlang/lib/xmerl-1.3.7 ERLANG_LIB_DIR_xmlrpc = not found ERLANG_LIB_VER_compiler = 5.0.2 ERLANG_LIB_VER_crypto = 3.4.1 ERLANG_LIB_VER_erlsom = not found ERLANG_LIB_VER_erts = 6.2 ERLANG_LIB_VER_eunit = 2.2.8 ERLANG_LIB_VER_inets = 5.10.3 ERLANG_LIB_VER_kernel = 3.0.3 ERLANG_LIB_VER_mnesia = 4.12.3 ERLANG_LIB_VER_public_key = 0.22.1 ERLANG_LIB_VER_sasl = 2.4.1 ERLANG_LIB_VER_ssl = 5.3.6 ERLANG_LIB_VER_stdlib = 2.2 ERLANG_LIB_VER_xmerl = 1.3.7 ERLANG_LIB_VER_xmlrpc = not found ERLANG_RELEASE = 17 ERLANG_ROOT_DIR = /usr/local/lib/erlang ERLC = /usr/local/bin/erlc ERLCFLAGS = ERL_LIBS = ESCRIPT = /usr/local/bin/escript EXEEXT = EXTRAINCLUDE = FGREP = /bin/grep -F GREP = /bin/grep HAVE_BAD_UNICODE = false HAVE_BAD_WILDCARD = false HAVE_CRYPTO_HASH = true HAVE_ERLANG_NOW = true HAVE_ERLANG_SENDFILE = true HAVE_INET_PARSE_STRICT_ADDRESS = true HAVE_SENDFILE = true HAVE_SSL_CLIENT_RENEGOTIATION = false HAVE_SSL_HONOR_CIPHER_ORDER = true HAVE_SSL_LOG_ALERT = true INSTALL = /usr/bin/install -c INSTALL_BUILDER = /home/klacke/installbuilder-5.4.14 INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LIBOBJS = LIBS = -lpam LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = MAKEINFO = ${SHELL} /home/klacke/yaws/ac-aux/missing makeinfo MAN = man MANIFEST_TOOL = : MKDIR_P = /bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = OBJDUMP = objdump OBJEXT = o OTOOL = OTOOL64 = PACKAGE = yaws PACKAGE_BUGREPORT = PACKAGE_NAME = yaws PACKAGE_STRING = yaws 2.0.2 PACKAGE_TARNAME = yaws PACKAGE_URL = PACKAGE_VERSION = 2.0.2 PATH_SEPARATOR = : PDFLATEX = pdflatex PS2PDF = ps2pdf RANLIB = ranlib SED = /bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip TODOS = todos UNIX2DOS = VERSION = 2.0.2 WERL = YAPP_VSN = 0.4.2 YAWS_VSN = 2.0.2 abs_builddir = /home/klacke/yaws/www/code abs_srcdir = /home/klacke/yaws/www/code abs_top_builddir = /home/klacke/yaws abs_top_srcdir = /home/klacke/yaws ac_ct_AR = ar ac_ct_CC = gcc ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = $${TAR-tar} chof - "$$tardir" am__untar = $${TAR-tar} xf - appsdir = $(localstatedir)/yaws bindir = ${exec_prefix}/bin build = x86_64-unknown-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = unknown builddir = . confdir = $(sysconfdir)/yaws datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} host = x86_64-unknown-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = unknown htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /home/klacke/yaws/ac-aux/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var logdir = $(localstatedir)/log/yaws mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} prefix = /home/klacke/yaws/_inst program_transform_name = s,x,x, psdir = ${docdir} sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . sysconfdir = ${prefix}/etc target = x86_64-unknown-linux-gnu target_alias = target_cpu = x86_64 target_os = linux-gnu target_vendor = unknown top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. wwwdir = $(localstatedir)/yaws/www yappdir = $(libdir)/yapp yawsdir = $(libdir)/yaws MODULES = myappmod.erl EXTRA_DIST = $(MODULES) EBIN_DIR = ../../examples/ebin EBIN_FILES = $(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign www/code/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign www/code/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include ../../include.mk include ../../erlang_deps.mk all-local: $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/code/Makefile.am���������������������������������������������������������������������0000664�0001750�0001750�00000001021�12605311413�013201� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include @top_srcdir@/include.mk MODULES = myappmod.erl EXTRA_DIST = $(MODULES) EBIN_DIR=@top_builddir@/examples/ebin EBIN_FILES=$(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/small.yaws���������������������������������������������������������������������������0000664�0001750�0001750�00000000057�12605311413�012260� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(_) -> {html, "XXXX"}. </erl> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/pcookie.yaws�������������������������������������������������������������������������0000664�0001750�0001750�00000002526�12605311413�012604� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> {ssi, "TAB.inc", "%%",[{"pcookie", "choosen"}]}. </erl> <div id="entry"> <h1>Persistent Cookies</h1> <p> We saw in the first <a href="cookies.yaws">cookie</a> example, how we assigned a special erlang process to handle each session. The cookie has an expiry date, and the correct thing would be to let the handling process live as long as the cookie is valid. This is not a good option. A better option is to store cookie in a persistant storage. This can be an ets table or a dets table. If we choose an ets table, the cookies will disappear when the yaws server is restarted, whereas if we choose a dets table, the cookies will survive daemon restarts. What to choose depends on the type of cookie information we have. </p> <p> The yaws code in <a href="setpcookie.yaws">setpcookie.yaws</a> sets the cookie in the browser. </p> <p>And the yaws code in <a href="readpcookie.yaws">readpcookie.yaws</a> will read the cookie </p> <p> Let's show some code. To set the cookie we we have: </p> <erl> out(A) -> yaws_api:pre_ssi_files(A#arg.docroot, ["setpcookie.yaws"]). </erl> <p> And to read the cookie, we have the following code: </p> <erl> out(A) -> yaws_api:pre_ssi_files(A#arg.docroot, ["readpcookie.yaws"]). </erl> </div> <erl> out(A) -> {ssi, "END2",[],[]}. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/news���������������������������������������������������������������������������������0000664�0001750�0001750�00000201155�12605311413�011144� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mon Jul 13 19:27:06 CEST 2015 Yaws 2.0 Fix Yaws build for Erlang 18.0 (now() deprecated) Renew self-signed ssl certificat to use the right signature algorithm support for the SSL 'log_alert' option expires fixes Fix possible XSS in yaws_outmod:crashmsg/3 rebar work. Rework how SSL protocol_version is handled Many minor bugfixes, tests and also docs. Tue Nov 11 17:17:37 CET 2014 Yaws 1.99 Major release, many enhancenements and bugfixes. Too many to list actually, see the git logs. The major ones though: combine multiple Accept-Encoding headers (steve) Massive autotools refactoring & cleanup (Christopher Faulet) Add SSL protocol_version configuration element (steve) Add 'honor_cipher_order' option in ssl part (Christopher Faulet) Mon Nov 4 19:22:42 CET 2013 Yaws 1.98 Bad HTTP 3.0 message sent to yaws, crashed the server entirely. Note this is crucial for yaws servers deployed on internet. (klacke) Use Yaws linked-in driver by default to send large file (capflam) Rebar work (Steve, Joseph Wayne Norton) Wed Oct 16 05:40:25 CEST 2013 Yaws 1.97 Webdav work, all webdav is now an appmod (tjeerd) New serveralias directive. Now it is possible to set alternate names for a virtual host. A server alias may contain wildcards. Inside a server definition wecan now have e.g serveralias = *.server.domain.com *.server?.domain.com (capflam) pam bug found by Jari Hellman optimized ssi code by storing binaries as the data chunks instead of lists of chars (klacke) Support message body in DELETE requests (capflam) Group automatically the server configurations in embedded mode. Now, Yaws groups the server configurations by itself when it is started in embedded mode. This is done when yaws_api:setconf/2 is called. (capflam) Use crypto:hash instead of crypto:sha to be compatible with R16B1. (Karolis Petrauskas ) Use proper linker command for drivers on OpenBSD (Francis Joanis ) Try to make the log directory if it doesn't exist. This happens only if logdir has a plus sign in front of it. E.g logdir = +path/to/log. (capflam, James Lee) Incorrect X-Forwarded-For header (Manuel Durán Aguete) Redhat /etc script bug fix by flavio-fernans Install procedure for FreeBSD wasn't correct (klacke) More rebar support (Steve, Tuncer) Fix option to enable/disable sendfile support in the configure script. file:sendfile/5 implementation is buggy (in R15 & R16). When async-threads are enabled, in efile driver, the tcp socket is set in blocking mode and thesendfile syscall is executed on an async-thread. So an unresponsive client could block it for a very long time and therefore block the async-thread. In this way, all async-threads could be easily blocked. So, by default, the use of sendfile is disable. (capflam) Add support of many options for tcp/ssl sockets (capflam) Fix mime_types.erl generation for a local installation of Yaws, (capflam) Tue Mar 19 17:53:00 CET 2013 Yaws 1.96 Websocket release, lots of work and rewrites of the websocket code which is now topnotch. Handle relative paths when Yaws is started in embedded mode (capflam) ensure compatibility with Erlang R13B04 (steve) Handle case with DOS attack towards pam login with embedded NUL chars in username or password. The protocol cannot handle NUL chars and Yaws dies (klacke) Extend syntax of redirect block to allow an optional status code. (capflam) Support multipart/form-data "name" with backslash at the end. (Johannes Weißl) Make be possible to chain appmods (capflam) Flush remaining data in case of 3xx redirect (capflam) Add support of the 'Vary' header in response (capflam) Add access functions for #gconf{} and #sconf{} records (capflam) Refactor WebSockets and add support of optional callback functions (capflam) Wed Oct 17 19:57:05 CEST 2012 Yaws 1.95 Feature relase, The --heart option didn't work as expected when yaws ran out of filedescriptors - capflam Major webdav overhaul by Tjeerd van der Laan. Lot's of improvements and general bugfixes. Added sorting of subconfigdir - Tjeerd van der Laan Added a fast dispatch module. This is for applications that only want the HTTP portion of yaws, i.e applications with very high performance requirements. A lot of the normal book keeping, tracing etc is ignored. Added RFC6265 compliant variant of yaws_api:set_cookie/3 - serge Fix SSL socket wrapping - capflam/Jean-Charles Campagne Parse extensions and trailing headers of chunked transfer encoded requests - capflam Optimize the ACL checks during the request's authentication -capflam Added support to configure ciphers in ssl - klacke dialyzer cleanup/improvements - Kenji Rikitake makefile / mime_type_c.beam cleanup - Kenji Rikitake add startup script for FreeBSD 9 (Thomas Elsgaard) make sure "rebar eunit" passes - steve new yaws_api:reformat_header/2 function - steve support Raspberry Pi in configure.in (Anders Nygren) Add basic websocket test - JD Bothma Make the mime types mappings configurable - capflam Add index_files directive into the server part configuration - capflam Refactor Set-Cookie/Cookie header parsing to follow RFC6265 - capflam enabled http client library options customization - Kaloyan Dimitrov Sun Jun 24 23:47:57 CEST 2012 Yaws 1.94 Bugfix release for bugs that sneaked into 1.93 The random patch for 1.93 wasn't good enough as discovered by Sergei Golovan, we need to cater for non printable chars (Sergei Golovan) add support for W3C Server-Sent Events (Steve) add easy getter/setter functions for #headers records (Steve) add reverse proxy intercept module capability (Steve) Patch from Nico Kruber to fix compile issue on OTP R13 Wed Jun 20 20:22:11 CEST 2012 Yaws 1.93 Security release Use crypto:rand_bytes() instead of the cryptographically weak random module. Swedish security consultant and cryptographer Kalle Zetterlund discovered a way to - given a sequence of cookies produced by yaws_session_server - predict the next session id. Thus providing a gaping security hole into yaws servers that use the yaws_session_server to maintain cookie based HTTP sessions (klacke/kallez) A denial of service bug has been corrected. Multippart POST processing on the yaws server side contained a list_to_atom/1 call which potentially makes it possible for an attacker to craft a continous list of POSTs, each potentially generating a new atom. This is a backwards incompatible fix since the upload code on the server side is user code. That code now needs to look for strings instead of atoms. For example the upload.yaws code in the www examples is changed. It searches now for the field "filename" instead of 'filename' (klacke) make sure to always send proper strings to file:write() while logging (Nicolas Adiba) default to a tcp queue backlog of 1024 (Nicolas Adiba) log debug messages to the error_logger for embedded mode (Nicolas Adiba) Add support of the 'OPTIONS' method when WebDav is enabled (Christopher Faulet) Several yaws_revproxy improvements and fixes. I think that finally, after many years of badness, Christopher Faulet has finally made the reverse proxy function as it shall. use request content type for SOAP responses (Steve) websocket work (Steve) typo in WWW-Authenticate handling leading to infinite recursion (nicad) add new HTTP status codes from RFC 6585 (Steve) Add support for precompressed static files (Christopher Faulet) Improve how the responses compression is handled (Christopher Faulet) configure ignores --libdir (steve) report uncaught exception as server error 500 (steve) fix yapp exclude_dir paths (Mikael Karlsson) Fix bugs in yaws_api:parse_multipart_post/1,2 for chunked requests (Christopher Faulet) Add options to configure deflate compression behaviour (Christopher Faulet) make handling of cookie names case insensitive According to RFC 2109 (steve) add rebar dependencies needed for SOAP applications (steve) add callback for abnormal websocket close (steve) note IPv4 or IPv6 as appropriate in munin statistics (Olivier Girondel) fix configure's ERTS version checking for file:sendfile/5 (steve) rebar work (tuncer) added soap12 capability (Kaloyan Dimitrov) Added facility for specifying an #auth record when starting embedded (Ulf Wiger) Manage all 'special' headers of #headers{} and #outh{} records (Christopher Faulet) Allow the server signature to be defined per virtual server (Christopher Faulet) fix log rotation on Windows, where fsync() is required to get the actual file size (Garret Smith) fixed wiki app XSS vulnerabilities (Sergei Golovan) Refactor flush/1 function to prevent DoS attack (Christopher Faulet) yaws now uses file:sendfile if available (R15B01 or newer) (tuncer/steve) Fri Dec 23 22:09:03 CET 2011 Yaws 1.92 Minor release, changes for OS X Lion for build and test (steve) Incorporation of various fixes from Klarna and Rickard Carlsson, makeing yaws_server upgrade-friendly and work with yaws --check (steve) allow functions to be specified as values in ehtml (steve) add config setting for acceptor pool size (steve) tex/doc work (steve) Populate soap_srv_mods field in yaws:setup_gconf/2 Essien Ita Essien don't setup dirs in embeddded mode (klacke) listen opts must be passed also to SSL sockets, Bug discovered and fixed by per Hedeland fix expires header time when crossing DST boundary (steve) fix CGI redirect HTTP status bug (steve) Lots of rebar/reltool work - steve/Tuncer Allow to pass options to erlsom - Willem de Jong R15B compat work - Tuncer update WebSockets implementation to support RFC 6455 - JD Bothma add support for HTTP PATCH (RFC 5789) - steve handle long HTTP header lines in R15B - steve Tue Aug 2 15:16:53 CEST 2011 Yaws 1.91 Minor release, with mostly small bugfixes, many tests added. Added support to generate and check strict xhtml output (klacke) Added possibility to turn off yaws log wrapping. This is useful for applications that embedd yaws and do not want that functionality at all (klacke) fix reverse proxy problem (issue #60) (Steve) let configure handle erlang built from git clone (Steve) Float fixes for json2.erl and json.erl (Nico Kruber) Support for halfword emulator (Steve) Several new testcases added by Christopher Faulet Fixes to the capflam patchset by Christopher Faulet Tue May 24 21:25:00 CEST 2011 Yaws 1.90 Highlights in this release are the capflam patchset, a really long list of general improvements by Jean-Sebastien Pedron and Christopher Faulet. Also rebar support has been added by Steve and Tuncer. Finally, Steve has added JSON 2.0 support. Thus this is a major release. Lot's of new little features and also lot's of bug fixes. always store a tuple in #headers.authorization (Jean-Sebastien Pedron) improve daemon status output (capflam) (Christopher Faulet) allow Server header customization (capflam) (Christopher Faulet) add shaper directive to control access (capflam) (Christopher Faulet) allow conf file pathname config with app env var (capflam) (Christopher Faulet) soft yaws shutdown (capflam) (Christopher Faulet) arg_rewrite mods can now return HTTP responses (capflam) (Christopher Faulet) support external handler to interpret php scripts (capflam) (Christopher Faulet) add status option to page options (capflam) (Christopher Faulet) allow multiple listen directives per server (capflam) (Christopher Faulet) server-specific logger_mod and auth_mod (capflam) (Christopher Faulet) support parsing of literal IPv6 addresses (capflam) (Christopher Faulet) allow hard reload of conf without stopping (capflam) (Christopher Faulet) add control for "Expires" and "Cache-Control" response headers (capflam) (Christopher Faulet) add "application/javascript" as a compressible mime type (capflam) (Christopher Faulet) use "partial_post_size" for chunked requests (capflam) (Christopher Faulet) authorization improvements, including ACLs like apache mod_access (capflam) (Christopher Faulet) Yaws can now be built with rebar (Tuncer Ayaz and Steve Vinoski) Updated Yaws JSON-RPC support to version 2.0 (Steve Vinoski) set HTTP_HOST properly for CGI (Steve) change sendfile driver handler to a gen_server (Steve) update mime.types from recent Apache web server sources (Steve) add binary option to multipart/form-data parsing (Steve) rewrite multipart/form-data POST handling, making memory consuption lower (Steve) add configurable access logging (Steve) Adding access functions for various Yaws records. (tobbe) yaws_session_server fixes for embedded mode (Tobbe) avoid keeping our own copy of ibrowse for testing (Steve) remove support for SOAP DIME attachments (Steve) fix EINTR handling in sendfile driver OSX related (Steve) A long series of dialyzer warnings fixed (klacke, Steve, Tuncer and Kostis) configure ERLBINDIR relative to ERLDIR (James Lee) teach linux build to distinguish 32- and 64-bit erlang (Steve) Pluggable ysession storage with mnesia sample in src/contrib (Nicolas Thauvin) add configure detection of erts bits support, required for websockets (Steve) security vulnerability for win32 reported at http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-4181 bug in upload to file code found by Mojito Sorbet add implementation of X-Forwarded-For header + docs (Fabian Linzberger) --running-config flag to query a running yaws for its config (klacke) fix typos on soap intro page (reported by Wes James) Fixed and updated SSL verify options. Fixed documentation for verify values to correspond to Erlang's SSL implementation. Updated #ssl{} and yaws:ssl_listen_opts/2 to include fail_if_no_peer_cert. (Per Andersson) Sat Sep 25 13:39:29 CEST 2010 Yaws 1.89 Maintenance release with a long series of fixes mostly from Steve Vinoski all.zip should not not include .yaws files, nor directories "protected" with an index file, nor directories protected by an auth directive. (Hans-Christian Esperer ) adjust to R14B change in gen_tcp:recv for {packet,http} mode Where we handle the return value of gen_tcp:recv while reading headers from the socket (such as with calls to yaws:do_recv), handle new R14B return values as well as existing return values for previous releases. (Steve) for portability, use erlang:md5 rather than crypto md5 Since OpenSSL availability on Windows for working with the crypto module is apparently questionable, use the erlang:md5 function in place of the crypto md5 functions. (Steve) websockets v76 update (Dominique Boucher) several fcgi updates and bugfixes (Steve) Add auth_skip_docroot server config variable (Christian Hennig) Fix use_old_ssl=bool() for R14A (Joseph Wayne Norton) add --umask option to yaws script (Steve) Some yapp work, added a simple example (Mikael Karlsson) performance enhancements (Steve) add support for PHP FCGI applications (Hans-Christian Esperer) fix cached process counter (Hans-Christian Esperer) return part headers from yaws_multipart:read_multipart_form (Steve, based on a patch from Dilshod Temirkhodjaev. patch for no-return-in-nonvoid-function error (Alexander Simonov) two-mode.el now works with emacs 23 (Steve) Allow "stream processes" to close the client socket (Steve) Augment yaws man page with --erlarg argument quoting info (Steve) Use gconf keepalive_timeout for connection lifetime (Brady McCary) handle multi-word arguments for heart restart command (Steve) Fix bug where yaws_api:parse_set_cookie tried to convert a record to lower case. (Anders Nygren) patch by Sergey Shilov to set old_ssl for embedded mode fix socket usage for FCGI authorization (bruno rijsman, steve vinoski) work around an erlang:open_port bug for CGI QUERY_STRING env var (Steve) Added a new configuration parameter called "keepalive_maxuses" which allows the yaws admin to close persistant connections after X number of uses. (Thomas O'Dowd ) improved embedded support (Steve) Thu Mar 18 21:51:32 CET 2010 Yaws 1.88 Highlights in this release are, new SSL implementation is now default, FCGI enhhancements and IPV6 support. ssl support for websockets, patch by wde Erroneous common log format entries, time should be surrounded by brackets (Klacke) When executing yaws --hup the order of the hosts in a virthost group wans't maintained, thus breaking the feature of pick first virthost on nomatch (Klacke) set nodelay on FCGI TCP connection, and avoid 0-length FCGI gen_tcp:recv (steve) Set {nodelay,true} on the TCP connection to the FCGI server to improve performance of small requests. (steve) The code receives packets from the FCGI server and for some cases was extracting length fields from some packets and then making further gen_tcp:recv calls based on those length values. The code was not checking for length values of 0 before calling recv, and passing 0 to recv means to return all available bytes. For both correctness and performance, the code must avoid the recv calls altogether when the length is 0. (steve) convert error atoms into error strings for fcgi_worker_fail (steve) IpV6 support The default value for partial_post_size was nolimit, not a good default value and also erroneoulsy documented (Klacke) An atempt at having utf8 characters in the host names for yaws servers. Probably not entirely correct, but it works. (Klacke) Anders Dahlin found that yaws log code doesn't delete the gen_event handler it adds error logger when terminating, that means that restarting yaws leaves old processes hanging around dialyzer work (Klacke) Closed Issue #31, made parsing of yaws.conf more tight complaining on e.g allowd_scripts = [ yaws ] fix for FastCGI/PHP Issue (http://github.com/klacke/yaws/issues#issue/30) (davide) auth through .yaws_auth files has become broken, (Klacke) allow caller to set Host header for SOAP requests (Steve) added support for OTP new ssl implementation ,Also set it as default. It's possible through yaws.conf to use the old SSL. The new seems to work well though, I've tested with a wide set of browsers, and in general it seems to work (klacke) Mon Jan 11 22:09:00 CET 2010 1.87 websocket support (davide and wde) conditional compile of websockets, only use if the chosen erl supports it (klacke/steve) patch by Andrei Soroker to strip the port part in #redir_self records - this patch may break some code, users that use redir_self() and unconditionally strip off their optional port number are affected support some extra status codes in code_to_phrase (steve) drop spaces before parsing ints - patch by Colm Dougan proper handling of "/" appmod with excluded paths (patch from wde) Added new unit tests for appmods, with both / and non-/ tests. The / tests include exclude_paths testing. (steve) patch from wde solving a problem with appmod exclude paths and verify_upgrade yaws_server: fixed the test for whether to close the socket. The yaws:outh_get_doclose() doesn't return a boolean and it requires the outh dicionary entry to be set (sometimes it isn't). (davide) do not pass the --id option if the default id is used (steve) Sun Dec 6 14:35:33 CET 2009 1.86 Mostly a bugfix release. Two new features. First the ability to exclude directories from an appmod. This is especially interesting for users that have an appmod at '/' but still want yaws to ship normal static contet such as js files and images. Secondly support for Forward proxying was added. Here is the changes list: It wasn't possible to handle huge files (above 2GIG ?) If sendfile hits EOVERFLOW send the file from Erlang code instead (Steve and klacke) json binary key support (TBBle) Forward proxy functionality added through a patch by Colm Dougan patch from anders dahlin to always populate yaws auth headers Added SSL support to stream_process_* functions. (davide) Added support for passing SSL configurations to start_embedded as a proplist (passing #ssl{} still works). (davide) Added support for excluding dirs from an appmod. (klacke) erasing the connection header must also set doclose to false (steve) Several soap patches by Eric Liang. docs, support on addtional specified prefix when rpc call by method: yaws_soap_lib:call, add the soap_srv_mods support, which can setup soap serve modules while yaws start. prevent crash caused by malicious client sending an empty Host header (steve) Several haXe fixes by Paul Hampson - Add example for haXe returning an error object, Document how to run haXe remoting sample under neko, Export haXe remoting handler function, Add example for JSON-RPC returning an error object, Allow JSON-RPC/haXe remoting handlers to send error objects. yaws_rpc produced non-compliant jsonrpc results. Looking at the JSON-RPC specification at http://json-rpc.org/wiki/specification the returned result of a call needs to contain an error field, with value null for the success case. The example json-rpc python client code on the json-rpc.org site expects this field to be present. (TBBle) Allow binaries as json values. (Matt Stancliff) mkcert SSL scripts (klacke) Sat Oct 17 22:56:36 CEST 2009 1.85 This is mostly (again) a bugfix/minor enhancement release. redirect bug reported by James Lee (steve) streamcontent_with_timeout bug , git issue #16 fixed (klacke) max number of connections patch by Kinoshita (klacke) updated mime.types from recent Apache web server sources (steve) config of partial_post_size = nolimit was broken (klacke) stopping yaws_sendfile thru supervisor does not hang - by ks (klacke) Major work on the auth code, Auth - unauthorized enhancements, Setup auth rewrite/cleanup, (Embedded) Config enhancements (Anders Dahlin) fix HTTP header case sensitivity problem in yaws_cgi (Bruno Rijsman) fix decode_base64 to return just a tuple in case of error (reported by Gabri add streamcontent_from_pid capability to allow direct streaming to socket (steve) Fixed support for Timeout=infinity in streamcontent_with_timeout. (davide) Use iolists instead of binaries for streamcontent_from_pid data, and add a new test for the streamcontent_from_pid feature (klacke) add --nodebug option (steve) determine gcc flags for 32-bit or 64-bit Erlang on OS X Snow Leopard (steve) add new multipart example yaws_multipart.erl (Praveen Ray) timezone format patch by Per Hedeland Patch from wde with support for virthosting several ssl serveres on the same IP. This makes sense if we have multiple subjectAltName in the ssl cert fixes for FCGI authorization (Bruno Rijsman), plus I cleaned up indentation and comments in yaws_cgi.erl Sun Jul 5 20:05:00 CEST 2009 1.84 patch from anders abramhamson - a bug with multipart posts New stats feature added by Olivier Girondel whereby (optionally) stats is collected for a virt server. Stats available from comand line (yaws --stats). There are also plugins for munin to graph the statistics. The authmod code should now be backwards compatible (faal) fixes for traffic tracing in reverse proxy mode (Olivier Girondel) Better error msg if erl is not found for win32 users (klacke) eliminate io_lib:format overhead in yaws_log:fmtnow (Steve) handle authdirs search properly when docroot not defined (Olivier Girondel) removed ancient backwards compat flag (klacke) Thu May 28 20:17:10 CEST 2009 Yaws 1.82 Have the yaws script set HOME if unset, this is required since some distros (Ubuntu) don't set HOME for code run under/etc/rc and erlexec requires HOME to be set. (Klacke) add extra cgi vars patch from joe_e_e new ebuild file for gentoo from joe_e_e patch by joe_e_e to move all files from /etc to /etc/yaws in the install script. This may cause some troubles for some users when upgrading. By default the make install target doesn't overwrite /etc files. Pay attention. added sendfile check for Darwin, since no sendfile is available on OS X Tiger (Steve) RSS fixes, (Steve) Several authentication fixes by Fabian Alenius. Changed the way authentication is done, added support for multiple authentication methods to be used for one directory and changed so that the 401 page can be customized similarly to the 404 page. In general this is a major cleanup of how authentication is done. Much better. One backwards incompat change here. Fabian Renamed yaws_401.erl to yaws_outmod.erl, which is probably a better name considering it's current use(it also displays the crashmsg). We need some better docs describing authentication !!! add date header to OPTIONS response (Steve) fix badmatch calling yaws_server:suffix_type from yaw_server:do_url_type when dav is true (Steve) Added fix and tests for github issue #2. Handle zero values for max_num_cached_files, max_num_cached_bytes, and max_size_cached_file to prevent infinite loops. (Steve) modify time_to_string to avoid slow io_lib:format (Steve) added sendfile check for Darwin, since no sendfile is available on OS X Tiger (Steve) document rss_dir (Steve) add ets-based yapp registry implementation for cases where mnesia is overkill (Steve) Fixed so that the HTTP status is set to 401 explicitly in yaws_server:handle_ut(...), previously out401 needed to return {status, ...} or status would default to 200. (Fabian Alenius) Mon Mar 9 21:48:18 CET 2009 Yaws 1.81 Moved the Yaws repository to http://www.github.som. See instructions at http://yaws.hyber.org/configuration.yaws on how to git clone Yaws. This is the first yaws release out of the github repo. The default Yaws wiki previously found at http://yaws.hyber.org/wiki has been moved to the wiki at github. New address of wiki is http://wiki.github.com/klacke/yaws. The previous (Erlang based wiki written by Johan Bevemyr) turned ... well unmodern, and was also plagued by spammers. Several cleanups by Hans Ulrich Niedermann, file perms, speling errors etc. remove leading slash in yapp_appmods examples (Tom McNulty) Add DIME support for SOAP Anders Nygren patch by Jouni Ryno finding broken fdsrv support Two patches by Joseph Wayen Norton, one dbg-bug and one providing better cookie support for yaws sesssions When yaws_ctl checks the CTL file to see if any current instance is running, check the socket opened to the port read from the CTL file to verify that the ephemeral port for that socket is not the same as the port read from the CTL file. This avoids a false positive caused by connecting the socket to its own port. (Steve Vinoski) cleaned up the redirect feature. It was poorly implemented and poorly documented. This fix is backwards compatible for users using redirect in confd.conf. However, it is NOT backwards compatible for embedded users that specify the redirect_map explicitly in their #sconf{} records. The required changes for embedded users should be evident from the code. The new required format is documented in the code where #sconf{} is defined (klacke) Thu Feb 12 22:58:16 CET 2009 Yaws 1.80 Full windows support with a proper .exe Windows installer (klacke) Added a timestamp check on the ssl cert/key files making it possible to just upload new cert/key files and do yaws --hup to automatically have the new cert/key files being used (klacke) Disgusting DOS attack discovered by Manuel Duran Aguete whereby if a neverendig series of headers are sent to yaws, we die of out of memory. Actual attack not described here. Contact me (klacke) if you're interested in the details and want a backport patch. I'm not really sure this is indeed the right procedure for announcing a DOS bug. (First time !!!) init_db patch cleanup by Liu Yubao patch by Liu Yubao to remove timeout in ssl accept add pkg-config support contributed by Olivier Girondel add --disable-sendfile option to configure, fix src/Makefile to clean yaws_configure.hrl (Steve) set HEART_COMMAND to allow a maximum of 5 restarts within any 60 second period (Steve) patch for queryparts that contain a question mark Document the --wait-started option for the yaws script (Steve) Fix the yaws script to allow --id ID to be passed after --wait-started (Steve) Allow optional wait time to be specified to yaws via --wait-started=<seconds> (Steve) added kpoll as default fix sendfile socket fd handling problems on 64-bit platforms (Steve) cygwin build patch by Davide marques stream content with a timeout patch from Davide Marques traffic trace was broken for certain types of requsts - found by wde Tue Jan 20 20:19:16 CET 2009 version 1.79 This release fixes the completely broken 1.78 release. So at last, we have good sendfile support. traffic trace was broken for certain types of requsts - found by wde Fixed several sendfile related bugs (vinoski) Improved yaws supervision structure (klacke) apply case-insensitive servername comparison patch from John Webb Thu Jan 8 22:00:51 CET 2009 version 1.78 Added --wait-started option to the yaws script (klacke) Added initial test suites (klacke) wrap log infinity bug found bt Phanikar.K allow keys with multiple values within opaque data fix handling of any existing listen_opts when reading listen_backlog conf variable (vinoski) incorporate Lev Walkin's patch for a configurable TCP listen backlog, adding yaws.conf support and documentation as well (vinoski) Added sendfile support, Works on Linux, FreeBSD and MacosX (vinoski) patch by wde@free.fr to let errormod_crash return {content, MimeType, Cont} added support/docs for authbind/privbind (klacke) handle 100 continue with POST patch by Haobu Yu configure/latex support and also slightly nicer listdir output by Hans Ulrich Niedermann better soap docs by Stu Bailey haxe serialization patch by Tomas Abrahamsson proc dict/proc_lib patch by Magnus F mime type patch by Tomas Abrahamsson POST patch for .yaws files (submitted by Tomas Abrahamsson) Several new MIME types added (vinoski) patch from magnus Froberg addressing a sync issue with add-sconf, e.g. dynamic updates that manifested itself when add_sconf was run several times in a row in certain scenarios. Implement special handling of the '*' URI for the OPTIONS method as specified in RFC2616 section 9.2. (vinoski) Added more thorough support for the HTTP OPTIONS method. For "active" applications such as appmods and yapps, the OPTIONS method is delivered through to the application for processing. For "passive" resources such as files and directories, OPTIONS returns a canned response just as before. (vinoski) added redirect_self() to yaws_api (klacke) yaws.rel.src was missing and better error printuts when yaws.conf is missing, patch by Vance Shipley solaris patch by Vance Shipley name of a file sent in a multipart request contains quotes, I get a crash pathh by Michael Slaski Blindly applied soap patch from Vance shipley addressing ... which causes operations to be missed when there are more than one port type in a WSDL. file descriptor leak found by John Fessenden modified patch by Robert David to add a hook to yaws session server when a session is gone Vance Shipley patch to correct error handling in yaws_soap_lib Mon Jun 16 22:44:45 CEST 2008 version 1.77 Content-Length chunked patch by Oleg Avdeev eaccess typos in confd_ctl.erl - Sergei Golovan added support for weird utf8 urlencoding Added the cygwin README by Bill Robtersson Added a 'make release' target in the top makefile. The release file picks up the versions of installed applications (erts,kernel, stdlib, sasl and mnesia). The product of this is a release package file (e.g. yaws-1.77.tar.gz) which can be installed on an embedded system using the SASL application release_handler. (Vance Shipley) added mnesia_dir support to the gconf record as per patch BY Richard Bucker The supervisor args were wrong, yaws shall have 1,0 restart strategy. This may break some backwards compat. Sites that ues yaws embedded need to check this. Added debug dump functionality (klacke) cygwin install patch by Bill Robertsson Adding files for Erlware. A very rough packaging of 1.76 has been released at erlware.org. See the doc/overview.edoc for more details. (tobbe) Major general code cleanup, finally got rid of all the export_all statements and in that process removed a bit of code that wasn't used (klacke) Better timeout support in yaws-session_server {page, P} patch by Robert David that handles better the case with a browser POST request patch by oleg avdeev for CRNL in revproxy embedded startup problem solved by Anders Nygren Make crashmsg set status code 500 Thu Apr 3 23:13:03 CEST 2008 version 1.76 Patch from Lev Walkin to pass HTTP_REFERER as well as the HTTP_IF headers to the cgi script Untabified all code. This is the right thing (TM) I've finally realized after programming for some 20 years with TABS in the files. (klacke) redhat /etc/init patch by Steve Vinoski quote patch for mnesiadir by Richard Bucker Added CGI documentation including a new page http://yaws.hyber.org/cgi.yaws (klacke) Several cleanups due to dialyzer, also moved the control file into users HOME directory so that we don't have the problem of writing in /var when we're running as non-root Adding support for: imports in the WSDL and support for more than one schema in the WSDL. Committed on behalf of: Willem de Jong. CGI should not just because it sees a Location: header do a 302, it is up the CGI script to set the correct status code (Sebastian strollo) Added some rudimentary docs in yaws.conf.5 for virtual directories. A feature added some time ago by Julian Noble, but never properly documented. (klacke) Sun Feb 3 2008 version 1.75 Better id handling for embedde startup (Klacke) Reintroduced the SPNEGO/GSSAPI auth support by Mikael Magnusson rpc patch by adam.boz@gmail.com updated yapp documentation and startup sequence of yapp to avoid deadlock situation when yapp is inncluded in other applications .app files. (Micke) Sat Dec 29 15:18:12 CET 2007 1.74 patch to make ssi work inside the crash handler from Michael FIG tidy up patch by Richard Buckner Logging work by Richar Bucker to make yaws work nice together with normal UNIX logrotate. race condition on update counter for a page, a pagecounter could be removed by another process Fixed a problem with heart restarting Yaws in a loop. Fixed a couple of problems with Yaws terminating on purpose when accept() fails. A bindings patch from Richard Bucker. silently discard traffic which isn't even HTTP. multivalued queryval/postval patch by yinso chen Thu Sep 20 15:09:35 CEST 2007 1.73 Sloppy ssl bug found by John Webb Wed Sep 19 23:17:47 CEST 2007 1.72 Even more bad properties found. Now all png, gif and wob (those are for the wiki) files have svn:mime-type application/octet-stream and no other properties. Finally fixed I hope. Fri Sep 14 21:52:52 CEST 2007 version 1.71 Lots of broken png anf gif files found in the wiki due to the cvs->svn conversion (klacke) Thu Sep 6 19:40:28 CEST 2007 version 1.70 Regular bugfix and small feature release. Revproxy bug found by igor goryachev. Started to use the new ssl:transport_accept() function, when accept fails, We now fail yaws entirely and it needs to be restarted by its supervisor or heart. If we have filedescriptor leaks, even outside of yaws, there is no good thing to do when accept fails. (klacke) A body message patch from Brian Templeton which cleaned up code and improved RFC 2616 compliance Added HTTPS env variable for trac (klacke) added x-javascript as a compressible mime type, patch by anthony shipman added a dir_listing function in yaws_api (klacke) fixed yapp dependencies to vdir handling, added local stylesheet and updated yapp_intro documentation (mikaelk) Virtual Directory support. ARG record and CGI variable changes. This change by Julian Noble was quite extensive. The feature is still completely undocumented - thus it is still experimental. Thu Feb 8 16:45:47 CET 2007 version 1.68 Forgot to update configure after the patch to configure.in for ubuntu edgy users in 1.67 Patch by Julian Noble to pass auth info over the CGI interface. Bugfix by Magnus Froberg: binding socket with fd_server now only listens to the specified IP address given in #sconf.listen Sun Feb 4 16:56:30 CET 2007 version 1.67 Bugfix release Removed the urlc_total counter - it didn't provide info which was worth the price of having it - Also Chris NewCombe reported troubles with the counter. (klacke) Added install of the priv/*.xsd files for the SOAP server (tobbe) Fixing yaws_api:find_cookie_val/2 which was broken (tobbe) Made the examples SOAP look prettier. (tobbe) Adding missing description on call to yaws_soap_srv:setup/2. (tobbe) patch from Dimitriy Kargapolov for tmpdir handling (klacke) Bugfix by Fredrik Thulin: The (undocumented) http_uri:parse/1 return format was changed between Erlang/OTP R11B-1 and R11B-2. (tobbe) Patch from Fredrik Thulin to make setuid_drv work better under ubuntu where gcc with some stack smashing tech is used to build, then we cannot use ld, we need to use ggc to greate the shared object. Appmod </, Mod> didn't work properly. Should be fixed now again !!!!! RSS The generated content was not valid RSS 2.0 content (tobbe) added ability to have config files in several files, patch from Sergei Golovan. Added call to callback function: M:F(cookie_expire) which is expected to return a proper cookie expire string. If non-existant, the default behaviour will prevail, i.e a session bases cookie lifetime. (tobbe) Extending yaws_api:find_cookie_val/2 to accept an #arg record as second argument as well. (tobbe) tweaked the haXe documentation (yariv) Sun Dec 17 20:58:21 CET 2006 version 1.66 Followup to the previous soap release. Adding entry for the yaws_soap_lib man-page (tobbe) pam fixes (made pam_wheel/pam_group work) (klacke) Tue Dec 12 10:51:18 CET 2006 version 1.66 pam fixes, e.g make pam_group.so/pam_wheel.so work (klacke) Full SOAP server/client implementation in Yaws bug found in path handling for yaws_dir by CEAN guys suppress dead client error msgs (klacke) shutdown fixes from Danile Luna added env DOCUMENT_ROOT to cgi env vars Michael FIG the pathinfo elem in #arg got wrong when appmod was / (klacke) start_embedded default flags patch by Jason Andersson Added option for having a module for handling authentication. (jb) Fix to yapp for starting dependencies, patch from Michael Leonhard added the client IP address to the #arg record added config flag 'use_large_ssl_pool = bool()' (klacke) Mon Sep 11 19:59:57 CEST 2006 version 1.65 patch by Chris NewCombeto handle PUT method better. Yapp added. Yaws application (Yapp) handler in yaws/applications/yapp directory "Drops" web applications independently of each other into an existing server where they get the default URL http://servername/application_name/. Yapps are simply Erlang/OTP applications with web pages in their priv/docroot directory (default). One can also configure private appmods, useful for controller parts in MVC like applications. (Mikael Karlsson) Haxe. Now compatible with the latest version of haXe. (yarivvv) New support to start Yaws as in embedded mode without having to fiddle with the boot script (etnt) patch from Matthew Reilley to handle new backwards non-compatible return value from OTP zlib:deflate/4 patch from anders nygren to handle absolute paths + yssi. patch from Magnus froberg to get better control over the files generated by 'yaws --check'. This is good if one wants to run i.e. xref and dialyzer also on all the generated .erl files from the --checker. empty array bug in json parse found by juhani and fixed by gaspar. appmod '/' was broken (klacke) Install, netbsd/yaws.sh: NetBSD support from Kuzma Bartosz. Thu Jul 13 13:07:10 CEST 2006 version 1.64 Fixes from Bengt Kleberg to make smtp.erl useful outside the webmail app. patch by Sergei Golovan which fixed a CGI bug and made yaws_ctl safe. install patches for macosX by Eric Baur. Added a haXe remoting adapter with documentation (yarivvv) made index.php autoload if it exists (klacke) added debian /etc startup script (klacke) Sun Jun 11 16:49:13 CEST 2006 version 1.63 Odd fix for MacOsX make behaviour. make install did not work. Wed Jun 7 22:10:44 CEST 2006 version 1.62 JSON Ajax code from Gaspar Chilingarov, I added docs describing an example. (klacke) run_erl and to_erl support patch from Mats Cronquist. yaws_zlib.erl: some bugs in non used code found by dialyzer. small fixes in the start script code (klacke) Fixes from Mikael Karlsson adding an event manager to Yaws whereby it is possible to add user defined gen_event handlers handling different "events" from Yaws. The only event sofar is config changes. This is needed for mikls "yapp" project which is a way to write yaws packages that can be "dropped" into an existing server. (No docs or anything released yet) Thu Apr 27 21:40:01 CEST 2006 Version 1.61 Started to write the ctl file, the file which contains the portnumber where the daemon is listening for ctl command to - /var/run/yaws/ctl-${ID}. The location is controllable through configure. Install scripts will make the /var/run/yaws dir writable to the world, each individual daemon which creates the ctl file will explicitly set the permissions on the ctl file to 600 - thus making it impossible for unauthorized users to control someone elses daemon. Root can control all daemons. changed Yaws license to proper BSD (klacke) Added startup script for FreeBSD Worked the Makefiles to properly support DESTDIR. This is useful for packagers creating deb, rpm, portage ... packages (klacke) Removed the ability to change userid. Also stopped writing to /tmp/yaws and started to write to ${HOME}/.yaws instead. This is much better since we cannot now ever get into the situations where file ownership and umask stop us from controlling a daemon. Note, this is a backwards incompatible change, all users that used the feature of letting Yaws change uid need to start using fdsrv instead. There is also a configurable in yaws.conf which makes it possible to write the tmp files to some other directory (klacke) Cleaned up the start flags to the yaws script, all old flags are still there for backward compatibility. Updated docs and and help output from the yaws script to reflect all new flags. Wiki fixes. Fixed error printouts; handle https and ftp links; updated READE (mbj) file descriptor leak bug found by Mats Cronqvist where each call to 'yaws -ls' left an unclosed descriptor in the server (klacke) Source code cleanup - added and #env record for environment passed to yaws. (klacke) yaws_ls enhancements by doccarcass@gmail.com Wed Feb 1 23:28:42 CET 2006 Version 1.58 pam and setuid_drv fixes for BSD by sstrollo yaws_ls (dir listing) enhancements by doccarcass@gmail.com RSS updates, more docs, Made month and days in RSS output to consist of two figures instead of just one. Fixed the RSS date format, as suggested by Daniel Kaminski. (Tobbe) Wiki, Fixed path to the application directory where yaws files are stored. (mikl) Added feature to not pick first sconf when virthosting. This is essential if we want explicit control over the virt hostnames. A commercial site called http://www.serious.com don't want http://fuckme.serious.com to ship the pages of the serious site :-) (klacke) DAV - reworked the DAV support a bit - don't use an appmod, instead yaws has built-in support for DAV methods. Added support for missing DAV methods (COPY etc). (mbj) Added support for the erlmerge/jungerl package 'fdsrv' which makes it possible to bind to privileged ports < 1024 even when we're not running as root. (klacke) changed so that an arg_rewrite_mod may temporarily change the docroot by changing the Arg#arg.docroot attribute (mikl) Added "pam" support for HTTP auth. (klacke) Wed Aug 17 14:54:06 CEST 2005 Version 1.57 rel/abs path patch by Rob Schmersel which fixed a problem in the wiki Rewrote yaws SSL code to use the packet http and packet line modes that are now supported in the OTP ssl module. Earlier this was all manual (and slow) code in yaws. Thus yaws/SSL servers are now considerably faster. The old yaws_ssl modules is no longer used. (klacke) Support clients that POST data with Transfer-Encoding chunked. This is used by some models of cellphones. Bug found by ermine@ermine.pp.ru (Klacke) Tmp dir patch by Karel Ostrovsky to better support tmp dir on Windows cgi port patch by joe_e_e Do not send the server port along with the host name in the CGI HTTP_HOST environment variable. Added HTTP_HOST env variable for CGI scripts (was required by sphpblog). (mikl) Thu Jun 16 13:42:50 CEST 2005, Version 1.56, Security update release. A bug was found by Daniel Fabian, SEC-Consult Unternehmensberatung GmbH whereby: If a null byte is appended to the filename of a yaws script (.yaws), the yaws webserver returns a page containing the source code of the according script. This flaw allows a malicious attacker to analyse the source code of the entire web application, which might result in the attacker gaining sensitive information like passwords. All versions of yaws older than 1.56 are vulnerable. For users running old yaws web servers, the following <a href="yaws-1.55_to_1.56.patch"> patch </a> can be applied. The patch is small and can easily be back ported to older yaws releases. Fri Jun 10 16:09:58 CEST 2005, Version 1.55 released. Feature release. Concept of redirect maps added. See documentation in yaws.conf man page. This makes it possible to redir entire parts of the docroot to another site (jb) Removed the forbidden code, the right thing to do when a script type is forbidden and we shall not run an interpreter on the script is to ship the script, but as text/plain instead of actually refusing to ship the data. Otherwise it's not possible to publish .php files at all on the web site. (klacke) Initial support for Web DAV added. This is as of yet undocumented. (tobbe) Added the possibility to have multiple docroots, where a page is searched in the list of docroots (klacke) Tue Apr 12 2005, Version 1.54 released. Bugfix release. Bug in SSL fixed, Bad line parsing in SSL mode, crashed when client sent headers split up in a certain way. (klacke) Removed the automatic htmlize on strings in ehtml, it was wrong ... to have it there. It's better for users that want it to explicitly add yaws_api:htmlize() to their strings This breaks code and is non backwards compatible. Be aware !! Also made {Tag, Attr} generate xhtml compliant code. (klacke) Cleaner shutdown (klacke) Many improvements to the chat server. (jb) When clearing the cache, yaws modules would remain loaded but be forgotten, resulting in a memory leak. (cschultz) Added possibility to name the module in a .yaws file using a syntax of < erl module="foobar"> .... < /erl> to always get a .yaws file named to a special fixed module name instead of the increasing m1,m2 .. modulenames. This is useful if we want to keep API functions in certain .yaws files and call these functions from other .yaws files. (klacke) Many reverse proxy bugs fixed. Maybe the reverse proxy is actually working now. It was never especially good. Try it. (mikl) Bug fixed with bindings that got propagated over to other later requests.Yet another put/get bug. Maybe it's time for an acronym there. YAPGB ??? (klacke) Better looking debug printouts. + dont overwrite trace_to_tty (-x commandline) if set on the commandline and also in the config file. Commandline should have precedense over config file directives. (klacke) Wrote an internals document. Available at <a href="http://yaws.hyber.org/internals.yaws"> http://yaws.hyber.org/internals.yaws</a> (klacke) Fri Feb 18, 2005 Bugfix release Fatso bug found by Fredrik Linder where yaws completely crash on bad URLs that for example contain space chars in the uri. This is the bug which provoked this imideate followup release. (klacke) Removed old broken URL decode code which was wrong. This code was added befor we actually understood how URLs are en/de coded (klacke, jb) Added example chat program (jb) Added new config opt fail_on_bind_err = Bool. The old behaviour was to silently accept (and log) server startup errors. This was due to a request from Tony Rogvall and the behaviour is bad, it's now back to the original behaviour where the entire yaws "application" fails if one virt server fails to gen_tcp:listen(). Mon Feb 14 2005, Version 1.52 released Minor feature release error condition bug in revproxy, found by tobbe. Revproxy is still not production quality. Experimental. embedded bugfix by Michael Arnoldus connection close bug found by Lennart Ostman made errorlog actually go out when conf is brokbroke e + daemon (klacke) Yaws is now RSS capable, see doc/README.rss (tobbe) Added a new example look and feel for the wiki (jb) Webmail, Fixed problem with login with empty fields in FireFox. (jb) wiki, Fixed minor unzip problem triggered when uploading zip archives with names containing spaces. (jb) Wed Dec 15 2004 Version 1.51 released Major feature release. Added support for config changes without stopping the running systems, virt servers can be added, removed and changed without affecting traffic. (klacke) wiki/searchPage.yaws: Added search code from Jouni Ryno (jb) Added client IP resolv for access log files (klacke) Safer make install target. Can't install if yaws is running (klacke) Updated both mail and wiki according to changed APIs for parse_multipart. (jb) Sat Dec 11 2004 Version 1.50 released Bugfix and docs release Running the wiki at the yaws site. Use it !!. No passwords.... <verbatim> tag added, this tag pretty much works as <pre> _should_ have worked. Nothing needs to be escaped, and code containing <, >, & etc can be entered freely. Writing code examples were driving me crazy. Inside both <pre> and <code> tags all HTML special chars have to be quoted, sucks. (klacke) Rewamped all docs with CSS and XHTML 1.0, beautiful and nice (klacke) Attach file problem in wiki (jb) Form post parameter was still always managed as atoms. This is a backwards incompatible change. It broke the wiki aswell as the upload example in the Yaws docs.However, the change is sound since it was easy to DOS a yaws server by sending file upload posts with new atoms. Eventually the atom table would overflow. However it does break code !!! (mikl) Added auto-generate all.zip to dir listings. It needs the zip command in the current path to function properly. To turn off, use dir_listsings = true_nozip. This is a feature for all of us that like to share copyrighthed material to friends that can't muster wget -r (mbj) Added relative path to ssi, ie {ssi, {rel_path, File}, ...} is now possible. (jb) mail app, Fixed refresh bug. (jb) Added example docs on how to stream data (klacke) modded patch by sebastian strollo to let request_url/1 and reformat_url/1 be proper inverses of each other (klacke) Made upgrading to new style Wiki templates smooth. If no template.html file exists in the WikiPreferences.files directory, then one is created. The same goes for template_info.html. (jb) Thu Sep 2, 2004 Version 1.49 released Bugfixrelease. Webmail fixes by jb, Add original message quoted in reply, Delete email bug fixed, Mailbox already locked bug, Improved attachment handling. Wiki fixes by jb, Made layout of wiki much more configurable using templates and ssi. You must run the script/updateWiki script after updating to this release. Bug found by David Welton, url on the form http://www.x.com?foo had yaws_api:queryval/2 return {nokey, "foo"} which is clearly wrong. New correct val is {"foo", undefined}. two-mode.el contributed by David Welton. Makes it easier to edit files with both erlang and html content. Typically the case for yaws files. cschultz did lots of stuff, Deflate rehaul: Now works with dynamic pages, Multiple dots in yaws file name caused trouble with pathinfo, fixed silly bug with content-range, cache fixes, Have several processes wait for SSL connections, so that one SSL negotiation in progress does not prevent other connections. Also, for the similar reasons, have use a timeout with SSL accepts. timeout are quite arbitrary. They are ok for my low traffic site. Streaming fixes, Rewrite requests with absolute URI to look like requests with a Host header. Small fix with embedded mode (it was completely non-working) by Jimmy Olgeni Addded configure option -with-defaultcharset (klacke) jb fixed a severe bug in ssi, Fixed bug in ssi code. Multichar delims were not handled properly. When a char of the delim string was found in the text it was deleted. patch from Paul Mahon to add PEER_ADDR to cgi env Mon Jun 7, 2004 Version 1.48 released This release contains both bugfixes as well as som minor new features. There was also a fairly ugly security hole in the example code which describes file uploads found and fixed. A Bug in yaws_api:request_url/1 was found by Einar Karttunen. The function didn't handle well the case with explicit port numbers in the URI. (klacke) Fixed the appmod code so that users of yaws_api:setconf/1 doesn't have to bother with the cahnge in internal representation of appmods. (klacke) Moved phpexe config variable from the sconf to the gconf, it doesn't make sence to have different phpexe paths for different virt servers. Users with old configs will get a warning when tying to specify a phpexe inside a virt server instead of inside the global config area. (klacke) New feature called "yssi". Yaws server side include. It's now possible to let the out/1 function return a tuple {yssi, PathToYawsFile.yaws"}. The new yaws file will be fully expanded, compiled and in general handled as a yaws file. This feature can probably be used to build all kinds of different cool stuff. (klacke) yaws_session_server ttl patch from Rob.Schmersel Patch from Fredrik Linder to make it easier to integrate yaws into apps that don't use the otp application framework at all. As usual updates both to the wiki and the webmail app by (jb) Patch from Jocke Grebeno which handles ssi support for ehtml code, not just ascii. We can now return {ssi, "@@", file.html, [{"FOO", "bar"}, {"BAZ", {ehtml, {p, [], "saab"}}}]} and it returns the expected. Documented is ssi.yaws. Security vulnerability in upload.yaws found by (mbj) Thu May 27, 2004 Version 1.47 released Appmods were slightly broken in 1.46 Wed May 26, 2004 Version 1.46 released Bugfix release. Several fixes to different parts of the web server. No new features. Debian support (David Welton) Embedded mode fixes (Jimmy Olgeni) Don't create no logs at all when logging is turned off bugfix (Jimmy Olgeni) SSL and large POSTs fix (cschultz) Compression and keep alive fix (cschultz) As usual, several fixes to the wiki and the webmail app (jbevemyr) An XSS vulnerability (lpsmith) Rewrote the url spliting (again) and also backed off from the redir when we get http://www.a.com/ and index.html exists. It's better to ship the file directly instead of sending a redir. (klacke) Reworked (and documented) the appmods a bit (klacke) Added a command line flag (yaws -ls) which lists existing yaws servers and their status on localhost. (klacke) Fri Apr 16, 2004 Version 1.45 released Minor bugfix release fixing up the some odd bugs introduced in the 1.43 rewite. Mar 18, 2004 Version 1.43 released This is a major release. Not so much for added functionality as for internal rewrites of the code. The release contains the following: Compression support using zlib. Still experimental. (cschultz) Minor bugfixes in the reverse proxy. This code is still not ready (klacke) Added a specific auth log which logs good and bad HTTP auth requests. QNX port (cschatz@networkadvantage.biz) Beautification of dir listings (cschultz) Never let ehtml generate extra spaces where it is not entirely correct (patch from tomas abrahamsson) Webmail app, Completed support for attachments, proper esacping, faster listing of large mboxes. Added sorting of mails (jb) Date header bug (chandru) postvar put/get bug fixed (hal snyder) Added yaws_api:query_url(Arg) which reconstructs the url from the original GET request. Added the "id = Key" configuration parameter. Earlier when we were running multiple yaws servers on the same machine, they had to run with different uid since yaws was writing temporary files under /tmp/yaws/${uid}. This is now changed and if we want 2 _different_ yaws servers on the same machine they must be given different "id" in their respective config files. The yaws ctl scripts, such as yaws -s and friends now have an extra (optional) "-j id" flag to control which specific instance of Yaws is ment. Added explicit support for Content-Length header from .yaws files for applications that require Content-Length instead of chunked encodings. Changed the #sconf{} and #gconf{} records so that all the booleans in those 2 records are now a bitmask flag. This is a slightly backwards incompatible change and it affects those that use Yaws in embedded mode where the #sconf and #gconf records are explicitly manipulated. It sholdn't be a big deal to change though. Workaround buggy otp error_logger_file_h which truncates the report file whenever it is reopened. Removed the calls inside the server that were doing list_to_atom/1 We were suceptible to DOS attacks. This is unfortunately a backwards incompatible change since it affects the return value from API functions yaws_api:parse_query/1 and yaws_api:parse_post/1. They both used to return lists on the form of {Key, Val} tuples where Key was an atom. It is now a string. There is a configuration option for yaws.conf which keeps the old (broken) behaviour. Optimized url parsing and removed at least one call to lists:flatten/1 in the fast path. Better support for old Netscape and the Connection: Keep-Alive header. More beautiful trace output. Try "yaws -i -x -T" More and better debug support. New install procedure with a more interesting yaws.conf template generated. Updated the ssl test certs that come with yaws. The old ones had expired. Feb 6, 2004 Version1.41 released Bugfixes and feature release. Minor bugfixes to the reverse proxy implementation (klacke) SSI for the ehtml expander as well as for normal usage. (klacke) Timestamp checks on SSI files (klacke) Wiki fixes (Johan Bevemyr) Return 404 instead of 403 when dir listings are disabled (Leon Smith) Added CGI variable REQUEST_URI (cschultz) Better dir listings with support for sort methods (Martin Bjorklund) Redir, bugs (one would thing we'd be able to do correct redirs by now .. ehh) (Leon Smithh) Support for 301,303, and 307 redirs (Johan Bevemyr) php executable is configurable (cschultz) Major feature enhancement, Support for a new concept called bindings, documented at http://yaws.hyber.org as well as in the man pages. (Joakim grebeno) More redir cleanup as well as introduction of redirect_local, {any_path, URI}} and made yaws_cgi use it. (cschultz) Made the webmail app able to render attachments (klacke) Dec 18, 2003 Version 1.40 released This is a major feature release. Experimental reverse proxy implementation <klacke@hyber.org> New feature, server side includes inside ehtml structure with variable expansion <klacke@hyber.org> yaws_html an HTML parser which produce ehtml output. The ideal tool for all of us who flunked artclass in highscool. Makes it very easy to rip page design from other sites (designed by those who went to the art classes) <jb@bevemyr.com>) A HTTP cookie parser <jb@bevemyr.com) A full blown easy to configure web mail application. It keeps no state, thus only requires the IP of the pop3/smtp servers to run. <jb@bevemyr.com) Some problems with ehtml expansion fixed <jb@bevemyr.com) Major overhaul of the docs, written description of embedded mode yaws <klacke@hyber.org) Don't fail fatal when we can't bind() <klacke@hyber.org) Time zone fix <magnus@nortelnetworks.com> Mime type fix <Rob Schmersel> tilde expansion and dir listings turned off by default, not on <jb@bevemyr.com> Many small fixes to the wiki by <jb@bevemyr.com> and <mikl> Oct 4, 2003. Version 1.31 released This is minor bugfix release Even more redir bugs fixed by Johan Bevemyr Runs on old erlangs (R7) (klacke) Compiles and runs nicely under win32 cygwin using native win32 erlang (klacke) Cosmetic fixes, docs update and return 403 on bad GETs by Leon Smith Aug 25, 2003. Version 1.30 released This is major feature release with many new features by in particular Carsten Schultz and Leon Smith plus the normal set of regular bugfixes. Setuid code had broken (klacke) Setcookie problem with lynx (Johan Bevemyr) Wiki: Thumbnail index to slideshow (Johan Bevemyr) Fixed Cross-Site Scripting vunerability (Leon Smith) url parsing rewritten in order to normalize the URL path in a more secure way (Leon Smith) Log file size for dynamic content also (Carsten Schultz) Full CGI and PHP support (Carsten Schultz) Added support for Content-Range, If-Range, If-Match (Carsten Schultz) HEAD handling rewritten (Carsten Schultz) Darwin MacOs X support (Eric Baur) Docs updated describing cgi and php support (Carsten Schultz) tty trace directly from command line for enhanced debugging Jun 1, 2003. Version 1.22 released This is bugfix release. cosmetic changes in ehtml output wiki install problems many fixes to the wiki ssl config was broken /etc/rc scripts for redhat/gentoo/suse linux a redir bug fixed. ebuild for gentoo added slideshow support added to the wiki cosmetic updates to the latex docs Mar 6, 2003. Version 1.2 released This is bugfix release. log fixes by brucefitzsimons cache bugs for URLs with a query part erlang compiler bug workaround, The erlang compiler isn't reentrant !!!!! Makefile cleanup my mikl Bugs in listdir May 3, 2003. Version 1.01 released This is bugfix release. Bug in ssl config passord parse found by Eric Pearson Bug in arg rewrite handling found and fixed by Taavi Talvik Bug with redir for missing trailing slash together with a query part of the url fixed, found by Erik Pearson Added the option of disabling dir_listings Added http version to access log messages Did away with the idiotic calls to id -u as well as the the broken grep in /etc/passwd. Also ensured that .yaws files with a query part don't end up in the cache. They need to be reparsed every time Fixed probles with paths that had a query part ending up in the cache Added proper support for 'if-none-match' with etag matching by Johan Bevemyr Skip empty space after an erl chunk in a .yaws file Handle http_error which is generated by the inet_drv.c code. This assumes a patch to the inet_drv.c that actually generates a http_error in this case. Default erl hangs there. Here is the inet_drv.c diff Jan 23, 2003. Version 1.0 released This is major release. Yaws is now in production quality. Some minor fixes to yaws_api. security bug found by jcortner@cvol.net can compile yaws file produced on win32, that is files with \r\n terminaded lines. Dec 1, 2002. Version 0.60 released This is minor maintenance release. Support to run Yaws first as root, then under a a non privileged user A bug in listdir together with ~username expansion fixed Bugs in wraplog fixed Nov 25, 2002. Version 0.59 released Lots of fixes and new features in this release. This release of Yaws is fast, it delivers 3000 static/dynamic pages/sec on my 2Ghz home box. Many fixes in the wiki, ~username expansion now works embedded mode is now fully implemented and functional many new configuration directives some backwards incompatible changes such as ssl config and yaws_api:parse_post_data/1. See the docs for details. Arg rewrite, customized errors etc. Lots of new documentation and new examples Optimized ehtml generation Oct 7, version 0.56 released. Improved file editing if in the wiki New returnvalue from out/1 <tt>break</tt> The wiki returns w3c compliant code New return value from out/1 <tt>{ehtml, ErlangTermStructure}</tt> Multiple users by uid can now run yaws simultaneously. Support for streamed large content from yaws code Never cache yaws files that disn't compile properly. Much more documentation, man page for yaws_api added a cookie_session-server for persistent cookie sessions full argument chunking support in Wiki Install properly on FreeBSD. Support for embedded mode (finally) bugfix for empty POST The shopingcart example is now fully implemented. Sep 2, version 0.54 released. Many fixes in the wikiweb by Johan Bevemyr, I'm now running a wikiweb at http://wiki.hyber.org Support for HTTP Basic authentication by Sean Hinde Better support for HTTP file upload by Johan and Sean Support for many more MIME types by compiling a mime.types file by klacke Support for OPTIONS http request by Johan Bevemyr Lots of non ready code for a webmail app by klacke. July 1, version 0.52 released. It contains a complete wiki web written by Johan Bevemyr with original code by Joe Armstrong. It also contains a series of minor and major bugfixes. Jun 19, version 0.51 released. Lot's of fixes. Return status 303 when browser asks for a dir URL without a trailing / in the http request. I've always wondered why apache does this. Now I know ... otherwise the relative URLs in /dir/index.html will be wrong when the browser tries to get them. Utilize this feature when listing dirs now, generate relative urls instead of absolute. Removed the default_server_on_this_ip option, the first virthosted server in the config will be default if no Host: header is present Made the Host: check to check for Host: host:port instead of just host when a server is run on a non-standard port. The browsers seem to set the Host: field to host:port Tobbe added the -r flag to the startscript Changed yaws_api:parse_post_data/1 so that it takes an arg struct as argument instead of querydata and added support for multipart form data in the process. Jun 16, version 0.50 released. A bug in setcookie fixed a proper /etc/rc/init.d script written. New flag, yaws -S which query status of the daemon. bug in cache reload fixed. Jun 13, version 0.48 released. It contains a complete rewrite of the API to generate dynamic content which makes it much easier to use. Furthermore this version accumulates output into larger chunks which makes it much faster the earlier versions. We can now serve 2500 dynamically generated HTML pages per second on a 2GhZ machine. A bug with iso 8859 chars in urls has been fixed. Etag header for static content and Cache-Control header for dynamic. Additional docs in the form of man pages. Version 0.40 released. Contains bugfixes and full SSL support as well as an embryo to WWW-Authenticate support. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/www/urandom.yaws�������������������������������������������������������������������������0000664�0001750�0001750�00000001713�12605311413�012615� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> out(A) -> Self = self(), spawn(fun() -> %% Create a random number {_A1, A2, A3} = now(), random:seed(erlang:phash(node(), 100000), erlang:phash(A2, A3), A3), Sz = random:uniform(100000), %% Read random junk S="dd if=/dev/urandom count=1 bs=" ++ integer_to_list(Sz) ++ " 2>/dev/null", P = open_port({spawn, S}, [binary,stream, eof]), rec_loop(Self, P) end), {streamcontent, "application/octet-stream", <<>>}. rec_loop(YawsPid, P) -> receive {P, {data, BinData}} -> yaws_api:stream_chunk_deliver(YawsPid, BinData), rec_loop(YawsPid, P); {P, eof} -> port_close(P), yaws_api:stream_chunk_end(YawsPid), exit(normal) end. </erl> �����������������������������������������������������yaws-2.0.2/www/embed.yaws���������������������������������������������������������������������������0000664�0001750�0001750�00000031624�12605311413�012230� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> {ssi, "TAB.inc", "%%",[{"embed", "choosen"}]}. </erl> <div id="entry"> <h1>Running yaws embedded in another application</h1> <p> Yaws is ideal for embedding within another larger erlang application. Many typical erlang applications are control applications in need of a webgui specific to the actual application. </p> <p>In order to run Yaws inside another application, we need to perform the following steps. </p> <ol> <li> <p>Either integrate Yaws into the build system of the larger application, or specifically provide the <code>ebin</code> path to Yaws for the larger application. </p> </li> <li><p> Provide the application environment <code>{embedded, true}</code> to Yaws.</p> </li> </ol> <p>Since the containing application typically has its configuration data fed from internal databases or other sources, it's usually not feasible to let Yaws read its configuration data from <code>/etc/yaws/yaws.conf</code> when it's running in embedded mode.</p> <p>To solve this, when Yaws is started in embedded mode, it doesn't read its configuration from <code>/etc/yaws/yaws.conf</code>, but rather it expects the larger application to feed its configuration through the function call <code>yaws_api:setconf(GC, Groups)</code>. The two arguments to this function are:</p> <ul> <li><p><code>GC</code>, which is a <code>#gconf{}</code> record</p></li> <li><p><code>Groups</code>, which is a list of lists of <code>#sconf</code> records</p></li> </ul> <p>The details of these records are unimportant, and we'll talk more about the <code>yaws_api:setconf</code> function later. First, let's discuss two ways applications can start Yaws in embedded mode.</p> <h2>Starting under your own supervisor</h2> <p>When not embedded, Yaws starts and runs as a regular application, but typically an application embedding Yaws wants to control it under its own supervisor(s). This means that an embedding application requires access to the Yaws supervisor child specifications. The exact list of Yaws child specifications depends on how the application intends to configure Yaws.</p> <p>The <code>yaws_api:embedded_start_conf/1,2,3,4</code> functions return the information an application needs to configure Yaws and start it under application supervisors. There are four variants of this function:</p> <ol> <li><p><code>yaws_api:embedded_start_conf/1</code> takes a single argument, which is the document root path for the web server. This variant uses default values for the <code>#gconf{}</code> and <code>#sconf{}</code> records.</p></li> <li><p><code>yaws_api:embedded_start_conf/2</code> takes a document root, same as the first variant above, and also a server configuration list. Such a list is either a list of properties for a single web server, or a list of property lists for multiple servers. We'll explain more about server configuration lists later, but for now note that they're used to create suitable <code>#sconf{}</code> record values. This variant uses a default value of the <code>#gconf{}</code> record.</p></li> <li><p><code>yaws_api:embedded_start_conf/3</code> takes a document root and a server configuration list, same as the second variant above, and also a global configuration list. Such a list is a property list that provides global configuration settings for the embedded Yaws instance, and is used to create a suitable <code>#gconf{}</code> record value. We'll explain more about global configuration lists later.</p></li> <li><p><code>yaws_api:embedded_start_conf/4</code>, the final variant, takes the same 3 arguments as the previous variant and also takes a string to identify the embedded Yaws instance.</p> </ol> <p>The values returned from these functions are described later.</p> <h3>Global configuration list</h3> <p>A global configuration list is a property list that provides global configuration settings for an embedded Yaws instance. Each property is a tuple consisting of property name and value. Allowed property names are those of the field names of the <code>#gconf{}</code> record type; see <code>yaws.hrl</code> for more details. An example global configuration list is shown below:</p> <div class="box"> <pre> [{logdir, "/var/log/my_server"}, {ebin_dir, ["/example1/ebin", "/example2/ebin"]}, {id, "my_server"}]. </pre> </div> <br/> <h3>Server configuration list</h3> <p>A server configuration list is a property list that provides configuration settings for a given web server instance. Because Yaws supports multiple servers simultaneously listening for requests, it's possible to supply a list of server configuration lists so that multiple servers can be configured in a single <code>yaws_api:setconf</code> function call. Each element in a server configuration list is a tuple consisting of property name and value. Allowed property names are those of the field names of the <code>#sconf{}</code> record type; see <code>yaws.hrl</code> for more details. An example server configuration list is shown below:</p> <div class="box"> <pre> [{docroot, "/var/yaws/www"}, {port, 8080}, {listen, {127,0,0,1}}, {appmods, [{"/", my_appmod}]}]. </pre> </div> <br/> <p>You can often determine the correct embedded server configuration by first creating a <code>yaws.conf</code> file specifying the desired configuration, running a stand-alone Yaws using it, and then dumping the server's configuration by executing the command <code>yaws --running-config</code>. Still, some elements of the embedded server configuration list are non-obvious. For example, to enable basic auth, you need to specify an <code>auth</code> proplist for each target directory. For example, to enable basic auth on "/":</p> <div class="box"> <pre> Docroot = "/var/yaws/www", Realm = "testrealm", SConfList = [{docroot, Docroot}, {port, 8080}, {listen, {0,0,0,0}}, {auth, [{docroot, Docroot}, {dir, "/"}, {realm, Realm}, {type, "Basic"}, {headers, ["WWW-Authenticate: Basic realm=\"", Realm, ["\"\r\n"]]}, {users, [{"foo","bar"}]}]}], </pre> </div> <p>If you want to enable auth on multiple directories, specify a <code> {auth, AuthProplist}</code> element for each one.</p> <p>Other elements, such as <code>dir_listings</code>, <code>access_log</code>, and <code>deflate</code>, are also non-obvious for embedded configuration because they're specified as part of the <code>#sconf.flags</code> element. You can find the server configuration flags, along with preprocessor macros for setting them on an <code>#sconf{}</code> record, in the <code>yaws.hrl</code> include file.</p> <h3>Using embedded_start_conf</h3> <p>The <code>yaws_api:embedded_start_conf/1,2,3,4</code> functions return <code>{ok, SCList, GC, ChildSpecs}</code>. The latter three elements of this tuple are described below.</p> <ul> <li><p><code>SCList</code> is a list of <code>#sconf{}</code> records created using the values from the passed-in server configuration lists</p></li> <li><p><code>GC</code> is a <code>#gconf{}</code> record created using the values from the passed-in global configuration list</p></li> <li><p><code>ChildSpecs</code> is a list of supervisor child specifications for the components of Yaws the application wants to start</p></li> </ul> <p>Below is an example of using the <code>yaws_api:embedded_start_conf/1,2,3,4</code> functions. It follows the steps of obtaining the embedded configuration and child specifications, starting the Yaws children under its own supervisor, and then setting the Yaws configuration.</p> <div class="box"> <pre> Id = "my_server", GconfList = [{logdir, "/var/log/my_server"}, {ebin_dir, ["/example1/ebin", "/example2/ebin"]}, {id, Id}], Docroot = "/var/yaws/www", SconfList = [{docroot, Docroot}, {port, 8080}, {listen, {127,0,0,1}}, {appmods, [{"/", my_appmod}]}], {ok, SCList, GC, ChildSpecs} = yaws_api:embedded_start_conf(Docroot, SconfList, GconfList, Id), %% assume our supervisor is registered as my_sup [supervisor:start_child(my_sup, Ch) || Ch <- ChildSpecs], %% now configure Yaws yaws_api:setconf(GC, SCList), </pre> </div> <h2>Starting yaws as an embedded application</h2> <p>The four functions <code>yaws:start_embedded/1,2,3,4</code> start Yaws in embedded mode using <code>application:start</code>. This approach differs from the one above in that the embedding application need not start any Yaws components under its own supervisors, nor does it need to explicitly call <code>yaws:setconf</code> to set the Yaws configuration. This approach is slightly simpler but also gives the embedding application less control over Yaws.</p> <p>The arguments for these four functions are identical to those for the <code>yaws_api:embedded_start_conf/1,2,3,4</code> functions described earlier.</p> <p>See the example below:</p> <div class="box"> <pre> %% %% Check with inet:i(). that you are listening to port 8000! %% 1> yaws:start_embedded("/home/tobbe/docroot"). %% %% Alternative ways %% 1> yaws:start_embedded("/home/tobbe/docroot", [{servername, "sej"}, {listen, {0,0,0,0}}]). 1> yaws:start_embedded("/home/tobbe/docroot", [{servername, "sej"}, {auth_log, false}, {listen, {0,0,0,0}}], [{copy_errlog, false}]). </pre> </div> <p>If you need more control on how to setup Yaws in embedded mode, use the <code>yaws_api:embedded_start_conf</code> functions instead. <h2>A very small example</h2> <p>We provide a minimal example that embeds Yaws in a small Erlang function.</p> <p>The <code>ybed</code> module is very small and is named <a href="code.yaws?file=/ybed.erl"><code>ybed.erl</code></a>. It has an accompanying simple supervisor named <a href="code.yaws?file=/ybed_sup.erl"><code>ybed_sup.erl</code></a>.</p> <p>If you compile both modules, you can run them as shown below:</p> <div class="box"> <verbatim> 1> {ok, Sup} = ybed_sup:start_link(). {ok,<0.40.0>} 2> =INFO REPORT==== 12-Apr-2010::02:42:09 === Yaws: Listening to 0.0.0.0:8888 for <1> virtual servers: - http://foobar:8888 under /tmp 2> </verbatim> </div> <p>The actual web server runs inside the larger application. The configuration of the web server was programmatically fed into Yaws from the surrounding application, in this case, the <a href="code.yaws?file=/ybed.erl"><code>ybed.erl</code></a> module. Note also how the Yaws children are started under the same <a href="code.yaws?file=/ybed_sup.erl"><code>ybed_sup.erl</code></a> supervisor as the code in the <code>ybed</code> module itself. <h2>The opaque field in the sconf structure </h2> <p>The <code>#sconf{}</code> record, which is constructed by the program that starts and configures Yaws, contains a field, <code>SC#sconf.opaque</code>.</p> <p>This field is passed into the <code>#arg{}</code> record, so that any application specific configuration data which is needed by the <code>.yaws</code> pages that make up the web GUI application, is easily available there.</p> <p>In essence, if we construct the <code>#sconf</code> as</p> <div class="box"> <verbatim> SC#sconf{opaque = {mystruct, foobar}, ..... </verbatim> </div> <p>A <code>.yaws</code> web page can then do:</p> <div class="box"> <verbatim> out(Arg) -> MyStruct = Arg#arg.opaque ..... </verbatim> </div> <p>thus passing data from the surrounding applications configuration routines down to each <code>.yaws</code> web page.</p> <p>Another important fact to consider when choosing whether to run your Yaws application as an embedded yaws app or not is that all the Yaws control functions are disabled when we use Yaws as an embedded web server, including capabilities such as <code>yaws --ls</code> and <code>yaws --stop</code>. Embedding thusassumes that you already have support for this type of functionality in your application.</p> <p>Finally, an interesting appmod definition that may apply to many embedded yaws installations is the <code>/</code> appmod with a set of exclude dirs. Here is an example server configuration list:</p> <div class="box"> <verbatim> [... {appmods, [{"/", myapp, [["js"], ["top", "static"], ["icons"]]}]}, ...]. </verbatim> </div> <p>or in <code>#sconf{}</code> record terms:</p> <div class="box"> <verbatim> SC#sconf{..... appmods = {"/", myapp, [["js"], ["top", "static"], ["icons"]]}, .... </verbatim> </div> </div> <erl> out(A) -> {ssi, "END2",[],[]}. </erl> ������������������������������������������������������������������������������������������������������������yaws-2.0.2/c_src/�����������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312014�010564� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/c_src/Makefile.in������������������������������������������������������������������������0000664�0001750�0001750�00000101046�12605311445�012562� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ @WITH_EPAM_TRUE@bin_PROGRAMS = epam$(EXEEXT) @HAVE_SENDFILE_TRUE@am__append_1 = yaws_sendfile_drv.la subdir = c_src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/ac-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" LTLIBRARIES = $(lib_LTLIBRARIES) setuid_drv_la_LIBADD = am_setuid_drv_la_OBJECTS = setuid_drv_la-setuid_drv.lo setuid_drv_la_OBJECTS = $(am_setuid_drv_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = setuid_drv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(setuid_drv_la_CFLAGS) \ $(CFLAGS) $(setuid_drv_la_LDFLAGS) $(LDFLAGS) -o $@ yaws_sendfile_drv_la_LIBADD = am__yaws_sendfile_drv_la_SOURCES_DIST = yaws_sendfile_drv.c \ hashtable.c hashtable.h hashtable_private.h @HAVE_SENDFILE_TRUE@am_yaws_sendfile_drv_la_OBJECTS = \ @HAVE_SENDFILE_TRUE@ yaws_sendfile_drv_la-yaws_sendfile_drv.lo \ @HAVE_SENDFILE_TRUE@ yaws_sendfile_drv_la-hashtable.lo yaws_sendfile_drv_la_OBJECTS = $(am_yaws_sendfile_drv_la_OBJECTS) yaws_sendfile_drv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(yaws_sendfile_drv_la_CFLAGS) $(CFLAGS) \ $(yaws_sendfile_drv_la_LDFLAGS) $(LDFLAGS) -o $@ @HAVE_SENDFILE_TRUE@am_yaws_sendfile_drv_la_rpath = -rpath $(libdir) PROGRAMS = $(bin_PROGRAMS) am__epam_SOURCES_DIST = epam.c @WITH_EPAM_TRUE@am_epam_OBJECTS = epam-epam.$(OBJEXT) epam_OBJECTS = $(am_epam_OBJECTS) epam_DEPENDENCIES = epam_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(epam_CFLAGS) $(CFLAGS) \ $(epam_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/ac-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(setuid_drv_la_SOURCES) $(yaws_sendfile_drv_la_SOURCES) \ $(epam_SOURCES) DIST_SOURCES = $(setuid_drv_la_SOURCES) \ $(am__yaws_sendfile_drv_la_SOURCES_DIST) \ $(am__epam_SOURCES_DIST) 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) # 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 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = $(ERLANG_INSTALL_LIB_DIR_yaws)/priv build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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 = $(ERLANG_INSTALL_LIB_DIR_yaws)/priv/lib libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ @WITH_EPAM_TRUE@epam_CFLAGS = $(EPAM_CFLAGS) $(EXTRAINCLUDE) -I$(ERLANG_ERTS_DIR)/include @WITH_EPAM_TRUE@epam_LDFLAGS = @WITH_EPAM_TRUE@epam_LDADD = @WITH_EPAM_TRUE@epam_SOURCES = epam.c lib_LTLIBRARIES = setuid_drv.la $(am__append_1) setuid_drv_la_CFLAGS = $(EXTRAINCLUDE) -I$(ERLANG_ERTS_DIR)/include setuid_drv_la_LDFLAGS = -module -avoid-version setuid_drv_la_SOURCES = setuid_drv.c @HAVE_SENDFILE_TRUE@yaws_sendfile_drv_la_CFLAGS = -DHAVE_SENDFILE $(EXTRAINCLUDE) -I$(ERLANG_ERTS_DIR)/include @HAVE_SENDFILE_TRUE@yaws_sendfile_drv_la_LDFLAGS = -module -avoid-version @HAVE_SENDFILE_TRUE@yaws_sendfile_drv_la_SOURCES = yaws_sendfile_drv.c hashtable.c hashtable.h hashtable_private.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign c_src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign c_src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } setuid_drv.la: $(setuid_drv_la_OBJECTS) $(setuid_drv_la_DEPENDENCIES) $(EXTRA_setuid_drv_la_DEPENDENCIES) $(AM_V_CCLD)$(setuid_drv_la_LINK) -rpath $(libdir) $(setuid_drv_la_OBJECTS) $(setuid_drv_la_LIBADD) $(LIBS) yaws_sendfile_drv.la: $(yaws_sendfile_drv_la_OBJECTS) $(yaws_sendfile_drv_la_DEPENDENCIES) $(EXTRA_yaws_sendfile_drv_la_DEPENDENCIES) $(AM_V_CCLD)$(yaws_sendfile_drv_la_LINK) $(am_yaws_sendfile_drv_la_rpath) $(yaws_sendfile_drv_la_OBJECTS) $(yaws_sendfile_drv_la_LIBADD) $(LIBS) 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 \ || test -f $$p1 \ ; 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) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(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: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list epam$(EXEEXT): $(epam_OBJECTS) $(epam_DEPENDENCIES) $(EXTRA_epam_DEPENDENCIES) @rm -f epam$(EXEEXT) $(AM_V_CCLD)$(epam_LINK) $(epam_OBJECTS) $(epam_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epam-epam.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setuid_drv_la-setuid_drv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yaws_sendfile_drv_la-hashtable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yaws_sendfile_drv_la-yaws_sendfile_drv.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< setuid_drv_la-setuid_drv.lo: setuid_drv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(setuid_drv_la_CFLAGS) $(CFLAGS) -MT setuid_drv_la-setuid_drv.lo -MD -MP -MF $(DEPDIR)/setuid_drv_la-setuid_drv.Tpo -c -o setuid_drv_la-setuid_drv.lo `test -f 'setuid_drv.c' || echo '$(srcdir)/'`setuid_drv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/setuid_drv_la-setuid_drv.Tpo $(DEPDIR)/setuid_drv_la-setuid_drv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='setuid_drv.c' object='setuid_drv_la-setuid_drv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(setuid_drv_la_CFLAGS) $(CFLAGS) -c -o setuid_drv_la-setuid_drv.lo `test -f 'setuid_drv.c' || echo '$(srcdir)/'`setuid_drv.c yaws_sendfile_drv_la-yaws_sendfile_drv.lo: yaws_sendfile_drv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(yaws_sendfile_drv_la_CFLAGS) $(CFLAGS) -MT yaws_sendfile_drv_la-yaws_sendfile_drv.lo -MD -MP -MF $(DEPDIR)/yaws_sendfile_drv_la-yaws_sendfile_drv.Tpo -c -o yaws_sendfile_drv_la-yaws_sendfile_drv.lo `test -f 'yaws_sendfile_drv.c' || echo '$(srcdir)/'`yaws_sendfile_drv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/yaws_sendfile_drv_la-yaws_sendfile_drv.Tpo $(DEPDIR)/yaws_sendfile_drv_la-yaws_sendfile_drv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yaws_sendfile_drv.c' object='yaws_sendfile_drv_la-yaws_sendfile_drv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(yaws_sendfile_drv_la_CFLAGS) $(CFLAGS) -c -o yaws_sendfile_drv_la-yaws_sendfile_drv.lo `test -f 'yaws_sendfile_drv.c' || echo '$(srcdir)/'`yaws_sendfile_drv.c yaws_sendfile_drv_la-hashtable.lo: hashtable.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(yaws_sendfile_drv_la_CFLAGS) $(CFLAGS) -MT yaws_sendfile_drv_la-hashtable.lo -MD -MP -MF $(DEPDIR)/yaws_sendfile_drv_la-hashtable.Tpo -c -o yaws_sendfile_drv_la-hashtable.lo `test -f 'hashtable.c' || echo '$(srcdir)/'`hashtable.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/yaws_sendfile_drv_la-hashtable.Tpo $(DEPDIR)/yaws_sendfile_drv_la-hashtable.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hashtable.c' object='yaws_sendfile_drv_la-hashtable.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(yaws_sendfile_drv_la_CFLAGS) $(CFLAGS) -c -o yaws_sendfile_drv_la-hashtable.lo `test -f 'hashtable.c' || echo '$(srcdir)/'`hashtable.c epam-epam.o: epam.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(epam_CFLAGS) $(CFLAGS) -MT epam-epam.o -MD -MP -MF $(DEPDIR)/epam-epam.Tpo -c -o epam-epam.o `test -f 'epam.c' || echo '$(srcdir)/'`epam.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epam-epam.Tpo $(DEPDIR)/epam-epam.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='epam.c' object='epam-epam.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(epam_CFLAGS) $(CFLAGS) -c -o epam-epam.o `test -f 'epam.c' || echo '$(srcdir)/'`epam.c epam-epam.obj: epam.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(epam_CFLAGS) $(CFLAGS) -MT epam-epam.obj -MD -MP -MF $(DEPDIR)/epam-epam.Tpo -c -o epam-epam.obj `if test -f 'epam.c'; then $(CYGPATH_W) 'epam.c'; else $(CYGPATH_W) '$(srcdir)/epam.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epam-epam.Tpo $(DEPDIR)/epam-epam.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='epam.c' object='epam-epam.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(epam_CFLAGS) $(CFLAGS) -c -o epam-epam.obj `if test -f 'epam.c'; then $(CYGPATH_W) 'epam.c'; else $(CYGPATH_W) '$(srcdir)/epam.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) all-local install-binPROGRAMS: install-libLTLIBRARIES installdirs: for dir in "$(DESTDIR)$(libdir)" "$(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: 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-generic clean-libLTLIBRARIES \ clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-libLTLIBRARIES 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 -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am all-local check check-am clean \ clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool clean-local cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-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-libLTLIBRARIES \ 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 \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS uninstall-libLTLIBRARIES all-local: post-build clean-local: $(AM_V_at)rm -f @top_builddir@/priv/epam $(AM_V_at)rm -fr @top_builddir@/priv/lib post-build: $(bin_PROGRAMS) $(lib_LTLIBRARIES) $(AM_V_at)$(INSTALL) -d @top_builddir@/priv/lib @WITH_EPAM_TRUE@ $(AM_V_at)$(INSTALL) -m 644 epam @top_builddir@/priv $(AM_V_at)$(INSTALL) -m 644 .libs/setuid_drv.so @top_builddir@/priv/lib @HAVE_SENDFILE_TRUE@ $(AM_V_at)$(INSTALL) -m 644 .libs/yaws_sendfile_drv.so @top_builddir@/priv/lib # Local Variables: # tab-width: 8 # End: # 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: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/c_src/yaws_sendfile_drv.c����������������������������������������������������������������0000664�0001750�0001750�00000022032�12605311412�014357� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Interface to sendfile system call for Yaws */ /* author: vinoski@ieee.org */ /* Created : 09 Nov 2008 by Steve Vinoski <vinoski@ieee.org> */ #ifdef HAVE_SENDFILE #include <errno.h> #include <stdint.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <ctype.h> #include <unistd.h> #if defined(__linux__) #include <sys/sendfile.h> #elif (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) #include <sys/socket.h> #include <sys/uio.h> #endif #include "erl_driver.h" #ifndef ERL_DRV_NIL #include "erl_driver_compat.h" #endif /* * previously drv_output(..., int len) * since R15B drv_output(..., ErlDrvSizeT len) * use int if OTP < R15B */ #if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 typedef int ErlDrvSizeT; #endif #include "hashtable.h" #define lshift_index(s, i, shift, t) (((t)((unsigned char*)(s))[i]) << (shift)) #define lshift32(s, i, shift) lshift_index(s, i, shift, uint32_t) #define lshift64(s, i, shift) lshift_index(s, i, shift, uint64_t) #define get_int32(s) (lshift32(s,0,24) | lshift32(s,1,16) | lshift32(s,2,8) | lshift32(s,3,0)) #define get_int64(s) (lshift64(s,0,56) | lshift64(s,1,48) | lshift64(s,2,40) | lshift64(s,3,32) | \ lshift64(s,4,24) | lshift64(s,5,16) | lshift64(s,6,8) | lshift64(s,7,0)) #define put_shift(i, s, idx, shift) (((unsigned char*)(s))[idx] = ((unsigned char)((i) >> (shift)) & 0XFF)) #define put_int32(i, s) do { \ put_shift(i, s, 0, 24); \ put_shift(i, s, 1, 16); \ put_shift(i, s, 2, 8); \ put_shift(i, s, 3, 0); \ } while(0) #define put_int64(i, s) do { \ put_shift(i, s, 0, 56); \ put_shift(i, s, 1, 48); \ put_shift(i, s, 2, 40); \ put_shift(i, s, 3, 32); \ put_shift(i, s, 4, 24); \ put_shift(i, s, 5, 16); \ put_shift(i, s, 6, 8); \ put_shift(i, s, 7, 0); \ } while(0) typedef union { void* hashkey; ErlDrvEvent ev_data; #ifdef _LP64 uint64_t socket_fd; #else uint32_t socket_fd; #endif } SocketFd; typedef struct { off_t offset; size_t count; ssize_t total; int file_fd; } Transfer; typedef struct hashtable* Transfers; typedef struct { ErlDrvPort port; Transfers xfer_table; } Desc; static unsigned int fdhash(void* k) { return ((SocketFd*)&k)->socket_fd; } static int fdeq(void* k1, void* k2) { return k1 == k2; } static ErlDrvData yaws_sendfile_drv_start(ErlDrvPort port, char* buf) { Desc* d = (Desc*)driver_alloc(sizeof(Desc)); if (d == NULL) return (ErlDrvData) -1; d->port = port; d->xfer_table = create_hashtable(8192, fdhash, fdeq); if (d->xfer_table == NULL) { driver_free(d); return (ErlDrvData) -1; } return (ErlDrvData)d; } static void yaws_sendfile_drv_stop(ErlDrvData handle) { Desc* d = (Desc*)handle; hashtable_destroy(d->xfer_table, 1); driver_free(d); } typedef union { off_t offset; size_t size; ssize_t count; uint64_t bits; unsigned char bytes[8]; } U64_t; typedef union { char* buffer; struct { U64_t offset; U64_t count; uint32_t out_fd; char filename[1]; }* args; struct { U64_t count; uint32_t out_fd; unsigned char success; char errno_string[1]; }* result; } Buffer; static ErlDrvSizeT set_error_buffer(Buffer* b, int socket_fd, int err) { char* s, *t; ErlDrvSizeT result_size = sizeof *(b->result); memset(b->result, 0, result_size); put_int32(socket_fd, &(b->result->out_fd)); s = erl_errno_id(err); if (strcmp(s, "unknown") == 0 && err == EOVERFLOW) { s = "EOVERFLOW"; } for (t = b->result->errno_string; *s; s++, t++) { *t = tolower(*s); } *t = '\0'; return result_size - 1 + t - b->result->errno_string; } static ssize_t yaws_sendfile_call(int out_fd, int in_fd, off_t* offset, size_t count) { #if defined(__linux__) off_t cur = *offset; ssize_t retval = sendfile(out_fd, in_fd, offset, count); if (retval >= 0 && retval != count) { if (*offset == cur) { *offset += retval; } retval = -1; errno = EAGAIN; } else if (retval < 0 && errno == EINTR) { errno = EAGAIN; } return retval; #elif defined(__APPLE__) && defined(__MACH__) off_t len = count; int retval = sendfile(in_fd, out_fd, *offset, &len, NULL, 0); if (retval < 0 && (errno == EAGAIN || errno == EINTR)) { *offset += len; errno = EAGAIN; } return retval == 0 ? len : retval; #elif defined(__FreeBSD__) off_t len = 0; int retval = sendfile(in_fd, out_fd, *offset, count, NULL, &len, 0); if (retval < 0 && (errno == EAGAIN || errno == EINTR)) { *offset += len; errno = EAGAIN; } return retval == 0 ? len : retval; #else errno = ENOSYS; return -1; #endif } static void yaws_sendfile_drv_output(ErlDrvData handle, char* buf, ErlDrvSizeT buflen) { int fd, socket_fd; Desc* d = (Desc*)handle; Buffer b; b.buffer = buf; socket_fd = get_int32(&(b.args->out_fd)); fd = open(b.args->filename, O_RDONLY | O_NONBLOCK); if (fd < 0) { ErlDrvSizeT out_buflen = set_error_buffer(&b, socket_fd, errno); driver_output(d->port, buf, out_buflen); } else { Transfer* xfer; SocketFd sfd; sfd.socket_fd = socket_fd; xfer = (Transfer*)hashtable_search(d->xfer_table, sfd.hashkey); if (xfer == NULL) { /* Transfer objects are intentionally not freed until the driver stops, or if an insertion error occurs below. */ xfer = (Transfer*)malloc(sizeof(Transfer)); if (xfer == NULL) { ErlDrvSizeT out_buflen = set_error_buffer(&b, socket_fd, ENOMEM); driver_output(d->port, buf, out_buflen); return; } if (!hashtable_insert(d->xfer_table, sfd.hashkey, xfer)) { ErlDrvSizeT out_buflen = set_error_buffer(&b, socket_fd, ENOMEM); driver_output(d->port, buf, out_buflen); free(xfer); return; } } xfer->file_fd = fd; xfer->offset = get_int64(&(b.args->offset.offset)); xfer->count = get_int64(&(b.args->count.size)); xfer->total = 0; #if defined(ERL_DRV_USE) && defined(ERL_DRV_WRITE) driver_select(d->port, sfd.ev_data, ERL_DRV_USE|ERL_DRV_WRITE, 1); #else driver_select(d->port, sfd.ev_data, DO_WRITE, 1); #endif } } static void yaws_sendfile_drv_ready_output(ErlDrvData handle, ErlDrvEvent ev) { Desc* d = (Desc*)handle; ssize_t result; off_t cur_offset; Transfer* xfer; SocketFd* sfd = (SocketFd*)&ev; xfer = (Transfer*)hashtable_search(d->xfer_table, sfd->hashkey); if (xfer == NULL) { /* fatal error, something is very wrong */ driver_failure_atom(d->port, "socket_fd_not_found"); return; } cur_offset = xfer->offset; result = yaws_sendfile_call(sfd->socket_fd, xfer->file_fd, &xfer->offset, xfer->count); if (result < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS || errno == EALREADY)) { if (xfer->offset != cur_offset) { off_t written = xfer->offset - cur_offset; xfer->count -= written; xfer->total += written; } } else { int save_errno = errno; ErlDrvSizeT out_buflen; char buf[36]; Buffer b; b.buffer = buf; memset(buf, 0, sizeof buf); #ifdef ERL_DRV_WRITE driver_select(d->port, ev, ERL_DRV_WRITE, 0); #else driver_select(d->port, ev, DO_WRITE, 0); #endif close(xfer->file_fd); if (result < 0) { out_buflen = set_error_buffer(&b, sfd->socket_fd, save_errno); } else { uint64_t total = xfer->total + result; put_int64(total, &(b.result->count.count)); put_int32(sfd->socket_fd, &(b.result->out_fd)); b.result->success = 1; b.result->errno_string[0] = '\0'; out_buflen = sizeof(*b.result); } xfer->file_fd = -1; xfer->offset = xfer->count = xfer->total = 0; driver_output(d->port, buf, out_buflen); } } static ErlDrvEntry yaws_sendfile_driver_entry = { NULL, yaws_sendfile_drv_start, yaws_sendfile_drv_stop, yaws_sendfile_drv_output, NULL, yaws_sendfile_drv_ready_output, "yaws_sendfile_drv", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ERL_DRV_EXTENDED_MARKER, ERL_DRV_EXTENDED_MAJOR_VERSION, ERL_DRV_EXTENDED_MINOR_VERSION, 0, NULL, NULL, NULL }; DRIVER_INIT(yaws_sendfile_drv) { return &yaws_sendfile_driver_entry; } #else #error "yaws_sendfile_drv not supported on this platform" #endif /* HAVE_SENDFILE */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/c_src/hashtable.c������������������������������������������������������������������������0000664�0001750�0001750�00000021500�12605311412�012602� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */ #include "hashtable.h" #include "hashtable_private.h" #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> /* Credit for primes table: Aaron Krowne http://br.endernet.org/~akrowne/ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html */ static const unsigned int primes[] = { 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741 }; const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]); const float max_load_factor = 0.65; /*****************************************************************************/ struct hashtable * create_hashtable(unsigned int minsize, unsigned int (*hashf) (void*), int (*eqf) (void*,void*)) { struct hashtable *h; unsigned int pindex, size = primes[0]; /* Check requested hashtable isn't too large */ if (minsize > (1u << 30)) return NULL; /* Enforce size as prime */ for (pindex=0; pindex < prime_table_length; pindex++) { if (primes[pindex] > minsize) { size = primes[pindex]; break; } } h = (struct hashtable *)malloc(sizeof(struct hashtable)); if (NULL == h) return NULL; /*oom*/ h->table = (struct entry **)malloc(sizeof(struct entry*) * size); if (NULL == h->table) { free(h); return NULL; } /*oom*/ memset(h->table, 0, size * sizeof(struct entry *)); h->tablelength = size; h->primeindex = pindex; h->entrycount = 0; h->hashfn = hashf; h->eqfn = eqf; h->loadlimit = (unsigned int) ceil(size * max_load_factor); return h; } /*****************************************************************************/ unsigned int hash(struct hashtable *h, void *k) { /* Aim to protect against poor hash functions by adding logic here * - logic taken from java 1.4 hashtable source */ unsigned int i = h->hashfn(k); i += ~(i << 9); i ^= ((i >> 14) | (i << 18)); /* >>> */ i += (i << 4); i ^= ((i >> 10) | (i << 22)); /* >>> */ return i; } /*****************************************************************************/ static int hashtable_expand(struct hashtable *h) { /* Double the size of the table to accomodate more entries */ struct entry **newtable; struct entry *e; struct entry **pE; unsigned int newsize, i, index; /* Check we're not hitting max capacity */ if (h->primeindex == (prime_table_length - 1)) return 0; newsize = primes[++(h->primeindex)]; newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize); if (NULL != newtable) { memset(newtable, 0, newsize * sizeof(struct entry *)); /* This algorithm is not 'stable'. ie. it reverses the list * when it transfers entries between the tables */ for (i = 0; i < h->tablelength; i++) { while (NULL != (e = h->table[i])) { h->table[i] = e->next; index = indexFor(newsize,e->h); e->next = newtable[index]; newtable[index] = e; } } free(h->table); h->table = newtable; } /* Plan B: realloc instead */ else { newtable = (struct entry **) realloc(h->table, newsize * sizeof(struct entry *)); if (NULL == newtable) { (h->primeindex)--; return 0; } h->table = newtable; memset(newtable[h->tablelength], 0, newsize - h->tablelength); for (i = 0; i < h->tablelength; i++) { for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) { index = indexFor(newsize,e->h); if (index == i) { pE = &(e->next); } else { *pE = e->next; e->next = newtable[index]; newtable[index] = e; } } } } h->tablelength = newsize; h->loadlimit = (unsigned int) ceil(newsize * max_load_factor); return -1; } /*****************************************************************************/ unsigned int hashtable_count(struct hashtable *h) { return h->entrycount; } /*****************************************************************************/ int hashtable_insert(struct hashtable *h, void *k, void *v) { /* This method allows duplicate keys - but they shouldn't be used */ unsigned int index; struct entry *e; if (++(h->entrycount) > h->loadlimit) { /* Ignore the return value. If expand fails, we should * still try cramming just this value into the existing table * -- we may not have memory for a larger table, but one more * element may be ok. Next time we insert, we'll try expanding again.*/ hashtable_expand(h); } e = (struct entry *)malloc(sizeof(struct entry)); if (NULL == e) { --(h->entrycount); return 0; } /*oom*/ e->h = hash(h,k); index = indexFor(h->tablelength,e->h); e->k = k; e->v = v; e->next = h->table[index]; h->table[index] = e; return -1; } /*****************************************************************************/ void * /* returns value associated with key */ hashtable_search(struct hashtable *h, void *k) { struct entry *e; unsigned int hashvalue, index; hashvalue = hash(h,k); index = indexFor(h->tablelength,hashvalue); e = h->table[index]; while (NULL != e) { /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v; e = e->next; } return NULL; } /*****************************************************************************/ void * /* returns value associated with key */ hashtable_remove(struct hashtable *h, void *k) { /* TODO: consider compacting the table when the load factor drops enough, * or provide a 'compact' method. */ struct entry *e; struct entry **pE; void *v; unsigned int hashvalue, index; hashvalue = hash(h,k); index = indexFor(h->tablelength,hash(h,k)); pE = &(h->table[index]); e = *pE; while (NULL != e) { /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { *pE = e->next; h->entrycount--; v = e->v; freekey(e->k); free(e); return v; } pE = &(e->next); e = e->next; } return NULL; } /*****************************************************************************/ /* destroy */ void hashtable_destroy(struct hashtable *h, int free_values) { unsigned int i; struct entry *e, *f; struct entry **table = h->table; if (free_values) { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); free(f->v); free(f); } } } else { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); free(f); } } } free(h->table); free(h); } /* * Copyright (c) 2002, Christopher Clark * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/c_src/setuid_drv.c�����������������������������������������������������������������������0000664�0001750�0001750�00000010223�12605311412�013017� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* author: klacke@hyber.org */ /* purpose, make us run under a different username */ /* as well as iface to some other idiotic syscalls */ /* FIXME replace this entirely with a proper */ /* posix interface */ #include <unistd.h> #include <sys/types.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <pwd.h> #include <stdlib.h> #include "erl_driver.h" static ErlDrvData setuid_start(ErlDrvPort port, char *buf); static void setuid_stop(ErlDrvData drv_data); static ErlDrvEntry setuid_driver_entry; /* buf is the name of the intented user */ static ErlDrvData setuid_start(ErlDrvPort port, char *buf) { char *t; char xbuf[BUFSIZ]; struct passwd *pe; if ((t = strchr(buf, ' ')) == NULL) return (ErlDrvData) -1; /* Rewind pw mapping */ setpwent(); t++; switch (*t++) { case 's': /* setuid */ while ((pe = getpwent())) { if (strcmp(pe->pw_name , t) == 0) { if ((setuid(pe->pw_uid) != 0) || (setreuid(pe->pw_uid, pe->pw_uid) != 0)) { return (ErlDrvData) -1; } sprintf(xbuf, "ok %u", (unsigned)pe->pw_uid); endpwent(); driver_output(port,xbuf, strlen(xbuf)); return (ErlDrvData) port; } } endpwent(); break; case 'n': { int uid = atoi(t); while ((pe = getpwent())) { if (pe->pw_uid == uid) { sprintf(xbuf, "ok %s", pe->pw_name); endpwent(); driver_output(port,xbuf, strlen(xbuf)); return (ErlDrvData) port; } } endpwent(); driver_output(port, "ok -", 4); return (ErlDrvData) port; } case 'g': /* getuid */ sprintf(xbuf, "ok %u", (unsigned)getuid()); driver_output(port,xbuf, strlen(xbuf)); return (ErlDrvData) port; case 'u': while ((pe = getpwent())) { if (strcmp(pe->pw_name , t) == 0) { sprintf(xbuf, "ok %u", (unsigned)pe->pw_uid); endpwent(); driver_output(port,xbuf, strlen(xbuf)); return (ErlDrvData) port; } } endpwent(); break; case 'h': while ((pe = getpwent())) { if (strcmp(pe->pw_name , t) == 0) { sprintf(xbuf, "ok %s", pe->pw_dir); endpwent(); driver_output(port,xbuf, strlen(xbuf)); return (ErlDrvData) port; } } endpwent(); break; } // In any case return error(?) for non void function return (ErlDrvData) -1; } static void setuid_stop(ErlDrvData drv_data) { } /* * Initialize and return a driver entry struct */ DRIVER_INIT(setuid_drv) { setuid_driver_entry.init = NULL; /* Not used */ setuid_driver_entry.start = setuid_start; setuid_driver_entry.stop = setuid_stop; setuid_driver_entry.output = NULL; setuid_driver_entry.ready_input = NULL; setuid_driver_entry.ready_output = NULL; setuid_driver_entry.driver_name = "setuid_drv"; setuid_driver_entry.finish = NULL; setuid_driver_entry.handle = NULL; setuid_driver_entry.control = NULL; setuid_driver_entry.timeout = NULL; setuid_driver_entry.outputv = NULL; setuid_driver_entry.ready_async = NULL; setuid_driver_entry.flush = NULL; setuid_driver_entry.call = NULL; setuid_driver_entry.event = NULL; setuid_driver_entry.extended_marker = ERL_DRV_EXTENDED_MARKER; setuid_driver_entry.major_version = ERL_DRV_EXTENDED_MAJOR_VERSION; setuid_driver_entry.minor_version = ERL_DRV_EXTENDED_MINOR_VERSION; setuid_driver_entry.driver_flags = 0; setuid_driver_entry.handle2 = NULL; setuid_driver_entry.process_exit = NULL; setuid_driver_entry.stop_select = NULL; return (ErlDrvEntry*) &setuid_driver_entry; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/c_src/hashtable.h������������������������������������������������������������������������0000664�0001750�0001750�00000016316�12605311412�012620� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */ #ifndef __HASHTABLE_CWC22_H__ #define __HASHTABLE_CWC22_H__ struct hashtable; /* Example of use: * * struct hashtable *h; * struct some_key *k; * struct some_value *v; * * static unsigned int hash_from_key_fn( void *k ); * static int keys_equal_fn ( void *key1, void *key2 ); * * h = create_hashtable(16, hash_from_key_fn, keys_equal_fn); * k = (struct some_key *) malloc(sizeof(struct some_key)); * v = (struct some_value *) malloc(sizeof(struct some_value)); * * (initialise k and v to suitable values) * * if (! hashtable_insert(h,k,v) ) * { exit(-1); } * * if (NULL == (found = hashtable_search(h,k) )) * { printf("not found!"); } * * if (NULL == (found = hashtable_remove(h,k) )) * { printf("Not found\n"); } * */ /* Macros may be used to define type-safe(r) hashtable access functions, with * methods specialized to take known key and value types as parameters. * * Example: * * Insert this at the start of your file: * * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value); * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value); * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value); * * This defines the functions 'insert_some', 'search_some' and 'remove_some'. * These operate just like hashtable_insert etc., with the same parameters, * but their function signatures have 'struct some_key *' rather than * 'void *', and hence can generate compile time errors if your program is * supplying incorrect data as a key (and similarly for value). * * Note that the hash and key equality functions passed to create_hashtable * still take 'void *' parameters instead of 'some key *'. This shouldn't be * a difficult issue as they're only defined and passed once, and the other * functions will ensure that only valid keys are supplied to them. * * The cost for this checking is increased code size and runtime overhead * - if performance is important, it may be worth switching back to the * unsafe methods once your program has been debugged with the safe methods. * This just requires switching to some simple alternative defines - eg: * #define insert_some hashtable_insert * */ /***************************************************************************** * create_hashtable * @name create_hashtable * @param minsize minimum initial size of hashtable * @param hashfunction function for hashing keys * @param key_eq_fn function for determining key equality * @return newly created hashtable or NULL on failure */ struct hashtable * create_hashtable(unsigned int minsize, unsigned int (*hashfunction) (void*), int (*key_eq_fn) (void*,void*)); /***************************************************************************** * hashtable_insert * @name hashtable_insert * @param h the hashtable to insert into * @param k the key - hashtable claims ownership and will free on removal * @param v the value - does not claim ownership * @return non-zero for successful insertion * * This function will cause the table to expand if the insertion would take * the ratio of entries to table size over the maximum load factor. * * This function does not check for repeated insertions with a duplicate key. * The value returned when using a duplicate key is undefined -- when * the hashtable changes size, the order of retrieval of duplicate key * entries is reversed. * If in doubt, remove before insert. */ int hashtable_insert(struct hashtable *h, void *k, void *v); #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \ int fnname (struct hashtable *h, keytype *k, valuetype *v) \ { \ return hashtable_insert(h,k,v); \ } /***************************************************************************** * hashtable_search * @name hashtable_search * @param h the hashtable to search * @param k the key to search for - does not claim ownership * @return the value associated with the key, or NULL if none found */ void * hashtable_search(struct hashtable *h, void *k); #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \ valuetype * fnname (struct hashtable *h, keytype *k) \ { \ return (valuetype *) (hashtable_search(h,k)); \ } /***************************************************************************** * hashtable_remove * @name hashtable_remove * @param h the hashtable to remove the item from * @param k the key to search for - does not claim ownership * @return the value associated with the key, or NULL if none found */ void * /* returns value */ hashtable_remove(struct hashtable *h, void *k); #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \ valuetype * fnname (struct hashtable *h, keytype *k) \ { \ return (valuetype *) (hashtable_remove(h,k)); \ } /***************************************************************************** * hashtable_count * @name hashtable_count * @param h the hashtable * @return the number of items stored in the hashtable */ unsigned int hashtable_count(struct hashtable *h); /***************************************************************************** * hashtable_destroy * @name hashtable_destroy * @param h the hashtable * @param free_values whether to call 'free' on the remaining values */ void hashtable_destroy(struct hashtable *h, int free_values); #endif /* __HASHTABLE_CWC22_H__ */ /* * Copyright (c) 2002, Christopher Clark * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/c_src/epam.c�����������������������������������������������������������������������������0000664�0001750�0001750�00000023527�12605311412�011604� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ #include <pam_appl.h> #include <stdio.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #define get_int16(s) ((((unsigned char*) (s))[0] << 8) | \ (((unsigned char*) (s))[1])) #define put_int16(i, s) {((unsigned char*)(s))[0] = ((i) >> 8) & 0xff; \ ((unsigned char*)(s))[1] = (i) & 0xff;} #ifndef D /*#define D(str) fprintf(stderr, (str)) */ #define D(str) #endif static int read_fill(int fd, unsigned char *buf, int len) { int i, got = 0; do { if ((i = read(fd, buf+got, len-got)) <= 0) { if (i == 0) return got; if (errno != EINTR) return got; i = 0; } got += i; } while (got < len); return (len); } static int write_fill(int fd, char *buf, int len) { int i, done = 0; do { if ((i = write(fd, buf+done, len-done)) < 0) { if (errno != EINTR) return (i); i = 0; } done += i; } while (done < len); return (len); } #if 0 /* * These functions are for binary prompt manipulation. * The manner in which a binary prompt is processed is application * specific, so these function pointers are provided and can be * initialized by the application prior to the conversation function * being used. */ static void pam_misc_conv_delete_binary(void *appdata, pamc_bp_t *delete_me) { PAM_BP_RENEW(delete_me, 0, 0); } int (*pam_binary_handler_fn)(void *appdata, pamc_bp_t *prompt_p) = NULL; void (*pam_binary_handler_free)(void *appdata, pamc_bp_t *prompt_p) = pam_misc_conv_delete_binary; #endif /* * This conversation function is supposed to be a generic PAM one. * Unfortunately, it is _not_ completely compatible with the Solaris PAM * codebase. * * Namely, for msgm's that contain multiple prompts, this function * interprets "const struct pam_message **msgm" as equivalent to * "const struct pam_message *msgm[]". The Solaris module * implementation interprets the **msgm object as a pointer to a * pointer to an array of "struct pam_message" objects (that is, a * confusing amount of pointer indirection). */ int misc_conv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *appdata_ptr) { int count=0; struct pam_response *reply; if (num_msg <= 0) return PAM_CONV_ERR; D(("allocating empty response structure array.")); reply = (struct pam_response *) calloc(num_msg, sizeof(struct pam_response)); if (reply == NULL) { D(("no memory for responses")); return PAM_CONV_ERR; } D(("entering conversation function.")); for (count=0; count < num_msg; ++count) { char *string=NULL; switch (msgm[count]->msg_style) { case PAM_PROMPT_ECHO_OFF: string = (char*)appdata_ptr; break; case PAM_PROMPT_ECHO_ON: string = (char*)appdata_ptr; break; case PAM_ERROR_MSG: if (fprintf(stderr,"%s\n",msgm[count]->msg) < 0) { goto failed_conversation; } break; case PAM_TEXT_INFO: if (fprintf(stdout,"%s\n",msgm[count]->msg) < 0) { goto failed_conversation; } break; #if 0 case PAM_BINARY_PROMPT: { pamc_bp_t binary_prompt = NULL; if (!msgm[count]->msg || !pam_binary_handler_fn) { goto failed_conversation; } PAM_BP_RENEW(&binary_prompt, PAM_BP_RCONTROL(msgm[count]->msg), PAM_BP_LENGTH(msgm[count]->msg)); PAM_BP_FILL(binary_prompt, 0, PAM_BP_LENGTH(msgm[count]->msg), PAM_BP_RDATA(msgm[count]->msg)); if (pam_binary_handler_fn(appdata_ptr, &binary_prompt) != PAM_SUCCESS || (binary_prompt == NULL)) { goto failed_conversation; } string = (char *) binary_prompt; binary_prompt = NULL; break; } #endif default: fprintf(stderr, "erroneous conversation (%d)\n" ,msgm[count]->msg_style); goto failed_conversation; } if (string) { /* must add to reply array */ /* add string to list of responses */ reply[count].resp_retcode = 0; reply[count].resp = string; string = NULL; } } *response = reply; reply = NULL; return PAM_SUCCESS; failed_conversation: D(("the conversation failed")); if (reply) { for (count=0; count<num_msg; ++count) { if (reply[count].resp == NULL) { continue; } switch (msgm[count]->msg_style) { case PAM_PROMPT_ECHO_ON: case PAM_PROMPT_ECHO_OFF: #if 0 _pam_overwrite(reply[count].resp); #endif free(reply[count].resp); break; #if 0 case PAM_BINARY_PROMPT: pam_binary_handler_free(appdata_ptr, (pamc_bp_t *) &reply[count].resp); break; #endif case PAM_ERROR_MSG: case PAM_TEXT_INFO: /* should not actually be able to get here... */ free(reply[count].resp); } reply[count].resp = NULL; } /* forget reply too */ free(reply); reply = NULL; } return PAM_CONV_ERR; } static struct pam_conv conv = { misc_conv, NULL }; static void werr(pam_handle_t *pamh, int sid, int ecode, char *phase) { char buf[BUFSIZ]; int len; sprintf(&buf[2], "pam %d no %s %s", sid, phase, pam_strerror(pamh, ecode)); len = strlen(&buf[2]); put_int16(len, &buf[0]); if (write_fill(1, buf, len+2) != len+2) exit(1); } static void wok(int sid) { char buf[BUFSIZ]; int len; sprintf(&buf[2], "pam %d yes", sid); len = strlen(&buf[2]); put_int16(len, &buf[0]); if (write_fill(1, buf, len+2) != len+2) exit(1); } static void wstart() { char buf[5]; sprintf(&buf[2], "ok"); put_int16(2, &buf[0]); if (write_fill(1, buf, 4) != 4) { exit(1); } } struct session { pam_handle_t *pamh; int sid; int session_mode; struct session *next; }; static struct session *sessions = NULL; static struct session *del_session(struct session **sp, int sid) { struct session *tmp; if (*sp == NULL) return NULL; if ((*sp)->sid == sid) { tmp = *sp; *sp = tmp->next; return tmp; } tmp = (*sp)->next; while (tmp != NULL) { if (tmp->sid == sid) { (*sp)->next = tmp->next; return tmp; } sp = &((*sp)->next); tmp = tmp->next; } return NULL; } static void do_auth(char *service, char*user, char*pwd, char* mode, int sid) { pam_handle_t *pamh=NULL; int retval; struct session *sessp; conv.appdata_ptr = (void*)strdup(pwd); retval = pam_start(service, user, &conv, &pamh); if (retval != PAM_SUCCESS) { werr(pamh, sid, retval, "start"); return; } pam_set_item(pamh, PAM_RUSER, user); retval = pam_authenticate(pamh, 0); if (retval != PAM_SUCCESS) { werr(pamh, sid, retval, "auth"); return; } if (mode[0] == 'A') { retval = pam_acct_mgmt(pamh, 0); if (retval != PAM_SUCCESS) { werr(pamh, sid, retval, "accounting"); return; } /*fprintf(stderr, "did ok acct \n\r");*/ } if (mode[1] == 'S') { retval = pam_open_session(pamh, 0); if (retval != PAM_SUCCESS) { werr(pamh, sid, retval, "session"); return; } /*fprintf(stderr, "did ok open sess \n\r"); */ } if ((sessp = malloc(sizeof(struct session))) == NULL) { werr(pamh, sid, -1, "malloc"); return; } if (mode[1] == 'S') sessp->session_mode = 1; else sessp->session_mode = 0; sessp->sid = sid; sessp->pamh = pamh; sessp->next = sessions; sessions = sessp; wok(sid); } int main(int argc, char *argv[]) { unsigned char lb[2]; unsigned char buf[BUFSIZ]; char *user; char *pwd; char *mode; int sid; int rval; struct session *sessp; // test clause if (argc == 4 ) { /* ./epam authmodule user passwd */ printf("testing service=%s u=%s pwd=%s\n", argv[1],argv[2], argv[3]); do_auth(argv[1], argv[2], argv[3], "AS", 33); exit(0); } wstart(); while (1) { if (read_fill(0, lb, 2) != 2) exit(1); rval = get_int16(lb); if (read_fill(0, buf, rval) != rval) exit(1); switch (buf[0]) { case 'a': // auth a user user = (char *)&buf[1]; pwd = user + strlen(user) + 1; mode= pwd + strlen(pwd) + 1; sid = atoi(mode + strlen(mode) + 1); do_auth(argv[1], user, pwd, mode, sid); break; case 'c': // close session sid = atoi((char *)&buf[1]); if ((sessp = del_session(&sessions, sid)) == NULL) { fprintf(stderr, "Couldn't find session %d\r\n", sid); break; } if (sessp->session_mode == 1) { pam_close_session(sessp->pamh, 0); /*fprintf(stderr, "did ok close sess \n\r");*/ } pam_end(sessp->pamh, PAM_SUCCESS); free(sessp); break; default: fprintf(stderr, "Bad op \n\r"); } } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/c_src/hashtable_private.h����������������������������������������������������������������0000664�0001750�0001750�00000005611�12605311412�014346� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */ #ifndef __HASHTABLE_PRIVATE_CWC22_H__ #define __HASHTABLE_PRIVATE_CWC22_H__ #include "hashtable.h" /*****************************************************************************/ struct entry { void *k, *v; unsigned int h; struct entry *next; }; struct hashtable { unsigned int tablelength; struct entry **table; unsigned int entrycount; unsigned int loadlimit; unsigned int primeindex; unsigned int (*hashfn) (void *k); int (*eqfn) (void *k1, void *k2); }; /*****************************************************************************/ unsigned int hash(struct hashtable *h, void *k); /*****************************************************************************/ /* indexFor */ static inline unsigned int indexFor(unsigned int tablelength, unsigned int hashvalue) { return (hashvalue % tablelength); }; /* Only works if tablelength == 2^N */ /*static inline unsigned int indexFor(unsigned int tablelength, unsigned int hashvalue) { return (hashvalue & (tablelength - 1u)); } */ /*****************************************************************************/ /*#define freekey(X) free(X)*/ #define freekey(X) /*****************************************************************************/ #endif /* __HASHTABLE_PRIVATE_CWC22_H__*/ /* * Copyright (c) 2002, Christopher Clark * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ �����������������������������������������������������������������������������������������������������������������������yaws-2.0.2/c_src/Makefile.am������������������������������������������������������������������������0000664�0001750�0001750�00000002406�12605311412�012543� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������bindir = $(ERLANG_INSTALL_LIB_DIR_yaws)/priv libdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/priv/lib if WITH_EPAM bin_PROGRAMS = epam epam_CFLAGS = $(EPAM_CFLAGS) $(EXTRAINCLUDE) -I$(ERLANG_ERTS_DIR)/include epam_LDFLAGS = epam_LDADD = epam_SOURCES = epam.c endif lib_LTLIBRARIES = setuid_drv.la setuid_drv_la_CFLAGS = $(EXTRAINCLUDE) -I$(ERLANG_ERTS_DIR)/include setuid_drv_la_LDFLAGS = -module -avoid-version setuid_drv_la_SOURCES = setuid_drv.c if HAVE_SENDFILE lib_LTLIBRARIES += yaws_sendfile_drv.la yaws_sendfile_drv_la_CFLAGS = -DHAVE_SENDFILE $(EXTRAINCLUDE) -I$(ERLANG_ERTS_DIR)/include yaws_sendfile_drv_la_LDFLAGS = -module -avoid-version yaws_sendfile_drv_la_SOURCES = yaws_sendfile_drv.c hashtable.c hashtable.h hashtable_private.h endif all-local: post-build clean-local: $(AM_V_at)rm -f @top_builddir@/priv/epam $(AM_V_at)rm -fr @top_builddir@/priv/lib post-build: $(bin_PROGRAMS) $(lib_LTLIBRARIES) $(AM_V_at)$(INSTALL) -d @top_builddir@/priv/lib if WITH_EPAM $(AM_V_at)$(INSTALL) -m 644 epam @top_builddir@/priv endif $(AM_V_at)$(INSTALL) -m 644 .libs/setuid_drv.so @top_builddir@/priv/lib if HAVE_SENDFILE $(AM_V_at)$(INSTALL) -m 644 .libs/yaws_sendfile_drv.so @top_builddir@/priv/lib endif # Local Variables: # tab-width: 8 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/�������������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311413�010276� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/mkdhparams/��������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311413�012425� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/mkdhparams/README��������������������������������������������������������������������0000664�0001750�0001750�00000000101�12605311413�013215� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Small script to generate a unique 2048-bit Diffie-Hellman group. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/mkdhparams/mkdhparams.sh�������������������������������������������������������������0000775�0001750�0001750�00000000061�12605311413�015030� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh openssl dhparam -out dhparams.pem 2048 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/dhparams.pem�������������������������������������������������������������������������0000664�0001750�0001750�00000000650�12605311412�012520� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-----BEGIN DH PARAMETERS----- MIIBCAKCAQEArTWf5IbXr+jWpZjCZCqaMN2H9v6oziEy1E6rU9eIIkWlCcKh556/ b8lYoZ/zuVR8aJ2o0m+o/tlOLfrgH7jkCYZEjFGLzs7W2PMv7b5liCYqRpSk2u/7 LMxuOTfT3YppNnFmAXz3PtGD0kozoO9tUHRDCrxBM7Vr+Ets76sIoutXQyS7SZ87 8WUpd3jQ3a//AMPzQ5h5daceAlXzmDBYjzDhiy+zahGLXQ7EDRJrwL6PPjGYvPog sPXtjmJDf7P8o/AapU2zQQBOVVD3pZ/ZKQ3Iy0MXshq3QhyVDZuogJ84zHsFJyDc XwRAjdx+/+12NV3P3jpZj8wreOyoRaZy4wIBAg== -----END DH PARAMETERS----- ����������������������������������������������������������������������������������������yaws-2.0.2/ssl/mkcert/������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�011562� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/mkcert/README������������������������������������������������������������������������0000664�0001750�0001750�00000000167�12605311412�012366� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Small script to generate a selfsigned cert. To make it a wildcard cert, just enter *.mydomain.com for the common name ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/mkcert/mkcert.sh���������������������������������������������������������������������0000664�0001750�0001750�00000000414�12605311412�013322� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh umask 077 && touch host.key host.cert host.info host.pem openssl genrsa 2048 > host.key openssl req -new -x509 -nodes -sha1 -days 3650 -key host.key > host.cert openssl x509 -noout -fingerprint -text < host.cert > host.info cat host.cert host.key > host.pem ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/mkcert_altname/����������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311413�013264� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/mkcert_altname/README����������������������������������������������������������������0000664�0001750�0001750�00000001202�12605311413�014057� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is a small README describing how to generate selfsigned certs with multiple subjectAltName which is required if we want to virthost several ssl servers on the same ip. Edit he openssl.cfg here - especially the part where we define a set of subjectAltName [sslserver] subjectAltName = @aliases [aliases] DNS.1 = bla.com DNS.2 = super.bla.com Create a new CA using # /usr/lib/ssl/misc/CA.pl -newca Create a CSR # openssl req -new -config ./openssl.cnf -newkey rsa:1024 -nodes -keyout yaws.ppk -out yaws.csr Sign the csr # openssl ca -config ./openssl.cnf -extensions sslserver -in yaws.csr -out yaws-cert.pem ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/mkcert_altname/openssl.cnf�����������������������������������������������������������0000664�0001750�0001750�00000022412�12605311413�015360� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # OpenSSL example configuration file. # This is mostly being used for generation of certificate requests. # # This definition stops the following lines choking if HOME isn't # defined. HOME = . RANDFILE = $ENV::HOME/.rnd # Extra OBJECT IDENTIFIER info: #oid_file = $ENV::HOME/.oid oid_section = new_oids # To use this configuration file with the "-extfile" option of the # "openssl x509" utility, name here the section containing the # X.509v3 extensions to use: # extensions = # (Alternatively, use a configuration file that has only # X.509v3 extensions in its main [= default] section.) [ new_oids ] # We can add new OIDs in here for use by 'ca' and 'req'. # Add a simple OID like this: # testoid1=1.2.3.4 # Or use config file substitution like this: # testoid2=${testoid1}.5.6 #################################################################### [ ca ] default_ca = CA_default # The default ca section #################################################################### [ CA_default ] dir = ./demoCA # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. #unique_subject = no # Set to 'no' to allow creation of # several ctificates with same subject. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/cacert.pem # The CA certificate serial = $dir/serial # The current serial number crlnumber = $dir/crlnumber # the current crl number # must be commented out to leave a V1 CRL crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem# The private key RANDFILE = $dir/private/.rand # private random number file x509_extensions = usr_cert # The extentions to add to the cert # Comment out the following two lines for the "traditional" # (and highly broken) format. name_opt = ca_default # Subject Name options cert_opt = ca_default # Certificate field options # Extension copying option: use with caution. # copy_extensions = copy # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs # so this is commented out by default to leave a V1 CRL. # crlnumber must also be commented out to leave a V1 CRL. # crl_extensions = crl_ext default_days = 365 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = sha1 # which md to use. preserve = no # keep passed DN ordering # A few difference way of specifying how similar the request should look # For type CA, the listed attributes must be the same, and the optional # and supplied fields are just that :-) policy = policy_match # For the CA policy [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional # For the 'anything' policy # At this point in time, you must list all acceptable 'object' # types. [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional #################################################################### [ req ] default_bits = 1024 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca # The extentions to add to the self signed cert # Passwords for private keys if not present they will be prompted for # input_password = secret # output_password = secret # This sets a mask for permitted string types. There are several options. # default: PrintableString, T61String, BMPString. # pkix : PrintableString, BMPString. # utf8only: only UTF8Strings. # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). # MASK:XXXX a literal mask value. # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings # so use this option with caution! string_mask = nombstr # req_extensions = v3_req # The extensions to add to a certificate request [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = AU countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Some-State localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) 0.organizationName_default = Internet Widgits Pty Ltd # we can do this but it is not needed normally :-) #1.organizationName = Second Organization Name (eg, company) #1.organizationName_default = World Wide Web Pty Ltd organizationalUnitName = Organizational Unit Name (eg, section) #organizationalUnitName_default = commonName = Common Name (eg, YOUR name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 # SET-ex3 = SET extension number 3 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name [ usr_cert ] # These extensions are added when 'ca' signs a request. # This goes against PKIX guidelines but some CAs do it and some software # requires this to avoid interpreting an end user certificate as a CA. basicConstraints=CA:FALSE # Here are some examples of the usage of nsCertType. If it is omitted # the certificate can be used for anything *except* object signing. # This is OK for an SSL server. # nsCertType = server # For an object signing certificate this would be used. # nsCertType = objsign # For normal client use this is typical # nsCertType = client, email # and for everything including object signing: # nsCertType = client, email, objsign # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment # This will be displayed in Netscape's comment listbox. nsComment = "OpenSSL Generated Certificate" # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer # This stuff is for subjectAltName and issuerAltname. # Import the email address. # subjectAltName=email:copy # An alternative to produce certificates that aren't # deprecated according to PKIX. # subjectAltName=email:move # Copy subject details # issuerAltName=issuer:copy #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem #nsBaseUrl #nsRevocationUrl #nsRenewalUrl #nsCaPolicyUrl #nsSslServerName [ v3_req ] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment [sslserver] subjectAltName = @aliases [aliases] DNS.1 = bla.com DNS.2 = super.bla.com [ v3_ca ] # Extensions for a typical CA # PKIX recommendation. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer:always # This is what PKIX recommends but some broken software chokes on critical # extensions. #basicConstraints = critical,CA:true # So we do this instead. basicConstraints = CA:true # Key usage: this is typical for a CA certificate. However since it will # prevent it being used as an test self-signed certificate it is best # left out by default. # keyUsage = cRLSign, keyCertSign # Some might want this also # nsCertType = sslCA, emailCA # Include email address in subject alt name: another PKIX recommendation # subjectAltName=email:copy # Copy issuer details # issuerAltName=issuer:copy # DER hex encoding of an extension: beware experts only! # obj=DER:02:03 # Where 'obj' is a standard or added object # You can even override a supported extension: # basicConstraints= critical, DER:30:03:01:01:FF [ crl_ext ] # CRL extensions. # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. # issuerAltName=issuer:copy authorityKeyIdentifier=keyid:always,issuer:always [ proxy_cert_ext ] # These extensions should be added when creating a proxy certificate # This goes against PKIX guidelines but some CAs do it and some software # requires this to avoid interpreting an end user certificate as a CA. basicConstraints=CA:FALSE # Here are some examples of the usage of nsCertType. If it is omitted # the certificate can be used for anything *except* object signing. # This is OK for an SSL server. # nsCertType = server # For an object signing certificate this would be used. # nsCertType = objsign # For normal client use this is typical # nsCertType = client, email # and for everything including object signing: # nsCertType = client, email, objsign # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment # This will be displayed in Netscape's comment listbox. nsComment = "OpenSSL Generated Certificate" # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer:always # This stuff is for subjectAltName and issuerAltname. # Import the email address. # subjectAltName=email:copy # An alternative to produce certificates that aren't # deprecated according to PKIX. # subjectAltName=email:move # Copy subject details # issuerAltName=issuer:copy #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem #nsBaseUrl #nsRevocationUrl #nsRenewalUrl #nsCaPolicyUrl #nsSslServerName # This really needs to be in place for it to be a proxy certificate. proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/yaws-key.pem�������������������������������������������������������������������������0000664�0001750�0001750�00000003213�12605311413�012471� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAzOM7Fiu/c1IuUVHFSJk3E1TO6Z7jQBoAx3vuotemo3HNM+iN gc8SpDNwSKC1eHqUYTQrNw+aHEpOAwgcsuUzkZwzMVgy2xJQZT2FLUODqgKGIJvg wArhTmQm2dxtgfVP6L7O78g9hTp7XLL06nJWALUgtK+7i5jMoxdnTkcHx4EPSZ/R N7BhT84PtdPMYyKhCHTC2RyiutG5gfH8kP0psaIdAWYI7jhc66pO86UtEbGFOWWh Yg1FFsb6ejP9N1i+yD9IUu6kh9XO155BeUu2NxJjL3kKh/nGhkWAW0DAMZuc48Up v63ya98laGAVg+qLRiZ5yI6gDlKxnLTLHMtgMwIDAQABAoIBAGk2TsNF19xqWSqd KQfs1eFxbYd+dggW0kueEp9AymuoJs3/H5uHMHVtjL1e+ZFSsRtxZLezpVndtk3M PqCHHoIpighO2F6y+uHiQ59IyjXlcecQ5Mr5S1WsDF9X2EwiItTMFwv+8ciWjX6+ zxINgKiAWrkufMpkvsEJZZ1G0HHbozPLC2yTzSijeJ49CLbmnXagtOZWoU1E7eN8 7Jsc//mtfWtEKfGx/MePZyp1js2LeJuul3JgDmYyeuWVe4k8jIxaaPlFuOwMee4I gruHYEL2Zbm6tc8iZe6s55Q47RRSlpBjtHHXDE/Avr56yOtre5bKjOYQ89DuNvJu 8XQ4Z6ECgYEA6RW9Ya4QYuwFVN0XQR26PPwCmdF93T1ZsxLqH1D0CnEoKVPUYyih BD48FQNmkM+YUIsxyndhcwgh250jLdgP1BMyRsgPeb9vuBIRZtEaJvXLAj60nnH1 3oJ0PpilSEl0+SEwI6loq//jQlIlPVeS+/I/bhPpywsZ+yiGbJlEFVkCgYEA4QfS 7HmUmcdSethUEI7wv3khhC6V/vPrp72mDhXtYRtIeAAi9YXYtz+5PUGOVeL+8iR2 2NdqG16tY3I3pFexTJ2J1s9MJBct+y96vnslKX0EjhvdPTqp0XXKqtzY1JBLb0vG 15UUh4e12tjQ4s5Vd8pHYYGDDwXqA3H19TYXlGsCgYBqZNUEcGrkbK3mVeFWhNZN Hg+l3N1iDq4SMrERyGcNGSfm7XAGLzaIdEwCn4HC2i/BnDgHHkUqN+0UjP7Q304i VPzfGFUQEtVRJVYyI4KXhBy9kpfpt0Uu40dih1Ty0S0GxyJtNNglovE+hbaf8IiU Xriba5WNbCzY21+41KEiSQKBgQCFHmy/KVkn80qukyR/ux9eFZknKavf64m/bCg8 cuo/JLWlD2ee2LQQC2lYfFxoIGVy9vE7a4tAb6yghKO324xt50/wPCctvmycCEVT Q2QDfApiyscA/qAQ4d6nXwgCDu4hA7G4PF+toTGKKfLACRF0ULwTSVsvWu9JZHP8 wCgIywKBgFBxP0IedijUKAmQ8AiGhk1X5qlaodYyCYAuTYsPg31KYhbLXCuvBIG5 PMcYXv6jN/KRNepxwnG9qr++z/Amc2KOmJEg3q4Bx309jl+P5RylcsTlFFXI8+Sa 4waFMXwfS14a7kfd3ZSuPRgTns5YvVDcEaR57OGdRhEj1rpbD3ea -----END RSA PRIVATE KEY----- �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ssl/yaws-cert.pem������������������������������������������������������������������������0000664�0001750�0001750�00000002735�12605311413�012646� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-----BEGIN CERTIFICATE----- MIIEJzCCAw+gAwIBAgIJAPzqpU19xVKfMA0GCSqGSIb3DQEBBQUAMIGpMQswCQYD VQQGEwJTRTEVMBMGA1UECAwMR29uZHdhbmFsYW5kMREwDwYDVQQHDAhZYXdzdG93 bjETMBEGA1UECgwKSHliZXIgSW5jLjEbMBkGA1UECwwSSmFuaXRvcmlhbCBzZWN0 aW9uMRIwEAYDVQQDDAlsb2NhbGhvc3QxKjAoBgkqhkiG9w0BCQEWG25vYm9keUBu b3doZXJlLmdvbmR3YW5hbGFuZDAeFw0xNTA0MjgwOTQ0MjFaFw0yNTA0MjUwOTQ0 MjFaMIGpMQswCQYDVQQGEwJTRTEVMBMGA1UECAwMR29uZHdhbmFsYW5kMREwDwYD VQQHDAhZYXdzdG93bjETMBEGA1UECgwKSHliZXIgSW5jLjEbMBkGA1UECwwSSmFu aXRvcmlhbCBzZWN0aW9uMRIwEAYDVQQDDAlsb2NhbGhvc3QxKjAoBgkqhkiG9w0B CQEWG25vYm9keUBub3doZXJlLmdvbmR3YW5hbGFuZDCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAMzjOxYrv3NSLlFRxUiZNxNUzume40AaAMd77qLXpqNx zTPojYHPEqQzcEigtXh6lGE0KzcPmhxKTgMIHLLlM5GcMzFYMtsSUGU9hS1Dg6oC hiCb4MAK4U5kJtncbYH1T+i+zu/IPYU6e1yy9OpyVgC1ILSvu4uYzKMXZ05HB8eB D0mf0TewYU/OD7XTzGMioQh0wtkcorrRuYHx/JD9KbGiHQFmCO44XOuqTvOlLRGx hTlloWINRRbG+noz/TdYvsg/SFLupIfVzteeQXlLtjcSYy95Cof5xoZFgFtAwDGb nOPFKb+t8mvfJWhgFYPqi0YmeciOoA5SsZy0yxzLYDMCAwEAAaNQME4wHQYDVR0O BBYEFBb8I1ZL/DhAUfj4QAR56kSaBZFZMB8GA1UdIwQYMBaAFBb8I1ZL/DhAUfj4 QAR56kSaBZFZMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAA4/MZNm P3W4v2cFqlrRvoT7OJHReiheO3t//b8JzySlsQSlzQPxE41sc7BdSMOsZIU7NDLK E8Ko9P/UtyF98IEG/Uz3+v93yY9qY4QxI0CW9LT9tfvAuVe92IDdq6iC+Ajl5ZQw xLx45VvrW9yqFhGnjsF4TFXEw4CtYg48Ei7zRkc0VMGD2jX2Z2lGHEsXt499pjgw QyH9V4pyluf1z4z1PyezD9HuSS1E3SNtOkbVANXYy0/+HGNaUN55MD1lCrDtmavA WkJOwmfFYSeQzRDsFF1cqEX6eoK5wIl414TXyBCNB/TbmbqqsfZieM4zAeriExhk yshzf9mWsgbrEtM= -----END CERTIFICATE----- �����������������������������������yaws-2.0.2/munin/�����������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�010622� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/munin/yaws_sent_�������������������������������������������������������������������������0000775�0001750�0001750�00000002231�12605311412�012641� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash # # YAWS server bytes sent # # Needs following minimal configuration in plugin-conf.d/munin-node: # [yaws*] # user root # # Magick markers #%# family=auto #%# capabilities=autoconf ID=`basename $0 | sed 's/^yaws_sent_//g'` TMPFILE=.yaws_sent_$ID STATS=`yaws --stats --id $ID | tail --lines=+2 > $TMPFILE` if [ "$1" = "autoconf" ]; then if which yaws > /dev/null; then echo yes exit 0 else echo no exit 1 fi fi if [ "$1" = "config" ]; then echo graph_title Bytes sent by server $ID echo graph_vlabel Bytes echo graph_category Yaws echo graph_args --base 1024 -l 0 while read line; do HOST=`echo $line | awk '{ print $1 }'` FIELD=`echo $HOST | sed 's/[\.:]/_/g'` echo $FIELD.label $HOST echo $FIELD.draw LINE2 echo $FIELD.type DERIVE echo $FIELD.min 0 done < $TMPFILE rm -f $TMPFILE exit 0 fi while read line; do HOST=`echo $line | awk '{ print $1 }'` FIELD=`echo $HOST | sed 's/[\.:]/_/g'` SENT=`echo $line | awk '{ print $5 }'` echo $FIELD.value $SENT done < $TMPFILE rm -f $TMPFILE exit 0 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/munin/README.munin�����������������������������������������������������������������������0000664�0001750�0001750�00000000554�12605311412�012553� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Usage: 1. Copy the scripts to /usr/share/munin/plugins 2. To graph statistics for the server "SERVER": # ln -s /usr/share/munin/plugins/yaws_hits_ /etc/munin/plugins/yaws_hits_SERVER # ln -s /usr/share/munin/plugins/yaws_sent_ /etc/munin/plugins/yaws_sent_SERVER 3. Change /etc/munin/plugin-conf.d/munin-node and add: [yaws*] user root 4. Restart munin-node ����������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/munin/yaws_hits_�������������������������������������������������������������������������0000775�0001750�0001750�00000002225�12605311412�012642� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash # # YAWS server hits # # Needs following minimal configuration in plugin-conf.d/munin-node: # [yaws*] # user root # # Magick markers #%# family=auto #%# capabilities=autoconf ID=`basename $0 | sed 's/^yaws_hits_//g'` TMPFILE=.yaws_hits_$ID STATS=`yaws --stats --id $ID | tail --lines=+2 > $TMPFILE` if [ "$1" = "autoconf" ]; then if which yaws > /dev/null; then echo yes exit 0 else echo no exit 1 fi fi if [ "$1" = "config" ]; then echo graph_title Hits for server $ID echo graph_vlabel Hits echo graph_category Yaws echo graph_args --base 1024 -l 0 while read line; do HOST=`echo $line | awk '{ print $1 }'` FIELD=`echo $HOST | sed 's/[\.:]/_/g'` echo $FIELD.label $HOST echo $FIELD.draw LINE2 echo $FIELD.type DERIVE echo $FIELD.min 0 done < $TMPFILE rm -f $TMPFILE exit 0 fi while read line; do HOST=`echo $line | awk '{ print $1 }'` FIELD=`echo $HOST | sed 's/[\.:]/_/g'` HITS=`echo $line | awk '{ print $4 }'` echo $FIELD.value $HITS done < $TMPFILE rm -f $TMPFILE exit 0 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/win32/�����������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312014�010435� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/win32/Makefile.in������������������������������������������������������������������������0000664�0001750�0001750�00000061305�12605311446�012437� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # sudo apt-get install mingw32 VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ bin_PROGRAMS = yaws$(EXEEXT) subdir = win32 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/build.xml.in $(top_srcdir)/ac-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = build.xml CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_yaws_OBJECTS = yaws-yaws.$(OBJEXT) yaws_OBJECTS = $(am_yaws_OBJECTS) yaws_DEPENDENCIES = 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 = yaws_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(yaws_CFLAGS) $(CFLAGS) \ $(yaws_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/ac-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(yaws_SOURCES) DIST_SOURCES = $(yaws_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) # 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 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ EXTRA_DIST = README.txt README.developer license.xml \ yaws.conf img yaws_CFLAGS = $(EXTRAINCLUDE) yaws_LDFLAGS = yaws_LDADD = yaws_SOURCES = yaws.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign win32/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign win32/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): build.xml: $(top_builddir)/config.status $(srcdir)/build.xml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ 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 \ || test -f $$p1 \ ; 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) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(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: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list yaws$(EXEEXT): $(yaws_OBJECTS) $(yaws_DEPENDENCIES) $(EXTRA_yaws_DEPENDENCIES) @rm -f yaws$(EXEEXT) $(AM_V_CCLD)$(yaws_LINK) $(yaws_OBJECTS) $(yaws_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yaws-yaws.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< yaws-yaws.o: yaws.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(yaws_CFLAGS) $(CFLAGS) -MT yaws-yaws.o -MD -MP -MF $(DEPDIR)/yaws-yaws.Tpo -c -o yaws-yaws.o `test -f 'yaws.c' || echo '$(srcdir)/'`yaws.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/yaws-yaws.Tpo $(DEPDIR)/yaws-yaws.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yaws.c' object='yaws-yaws.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(yaws_CFLAGS) $(CFLAGS) -c -o yaws-yaws.o `test -f 'yaws.c' || echo '$(srcdir)/'`yaws.c yaws-yaws.obj: yaws.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(yaws_CFLAGS) $(CFLAGS) -MT yaws-yaws.obj -MD -MP -MF $(DEPDIR)/yaws-yaws.Tpo -c -o yaws-yaws.obj `if test -f 'yaws.c'; then $(CYGPATH_W) 'yaws.c'; else $(CYGPATH_W) '$(srcdir)/yaws.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/yaws-yaws.Tpo $(DEPDIR)/yaws-yaws.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yaws.c' object='yaws-yaws.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(yaws_CFLAGS) $(CFLAGS) -c -o yaws-yaws.obj `if test -f 'yaws.c'; then $(CYGPATH_W) 'yaws.c'; else $(CYGPATH_W) '$(srcdir)/yaws.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) 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: 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-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local 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 -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-local .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-data-local 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 mostlyclean-libtool \ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-local install-data-local: $(AM_V_at)$(INSTALL) -m 644 @srcdir@/yaws.conf $(DESTDIR)$(yawsdir) $(AM_V_at)$(INSTALL) -m 644 @srcdir@/README.txt $(DESTDIR)$(yawsdir) $(AM_V_at)$(INSTALL) -m 644 @top_srcdir@/vsn.mk $(DESTDIR)$(yawsdir) $(AM_V_at)$(INSTALL) -m 644 @top_srcdir@/LICENSE $(DESTDIR)$(yawsdir) $(AM_V_at)cp -r @top_srcdir@/ssl $(DESTDIR)$(yawsdir) uninstall-local: $(AM_V_at)rm -fr $(DESTDIR)$(yawsdir)/ssl $(AM_V_at)rm -f $(DESTDIR)$(yawsdir)/yaws.conf \ $(DESTDIR)$(yawsdir)/README.txt \ $(DESTDIR)$(yawsdir)/LICENSE \ $(DESTDIR)$(yawsdir)/vsn.mk mkinstaller: install $(AM_V_at)[ -n $(UNIX2DOS) ] && CONV=$(UNIX2DOS) || CONV=$(TODOS); \ $${CONV} $(DESTDIR)$(yawsdir)/LICENSE 2>/dev/null; \ for ext in txt erl conf html yaws js pem; do \ find $(DESTDIR)$(yawsdir) -name "*.$${ext}" -exec $${CONV} {} \; 2>/dev/null;\ done $(AM_V_at)$(INSTALL) -m 644 @builddir@/build.xml $(DESTDIR)$(yawsdir) $(AM_V_at)(cd $(DESTDIR)$(yawsdir) && $(INSTALL_BUILDER)/bin/builder build build.xml windows) $(AM_V_at)mv $(INSTALL_BUILDER)/output/*.exe @top_srcdir@ $(AM_V_at)rm -f $(DESTDIR)$(yawsdir)/build.xml # Local Variables: # tab-width: 8 # End: # 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: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/win32/yaws.conf��������������������������������������������������������������������������0000664�0001750�0001750�00000011051�12605311413�012207� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# conf for yaws # First we have a set of globals that apply to all virtual servers # This is the directory where all logfiles for # all virtual servers will be written. logdir = "%yawsdir%/logs" # These are the paths to directories where additional # beam code can be placed. The daemon will add these # directories to its search path. ebin_dir = "%yawsdir%/examples/ebin" ebin_dir = "%yawsdir%/yaws/ebin" # This is a directory where application specific .hrl # files can be placed. Application-specific .yaws code can # then include these .hrl files. include_dir = "%yawsdir%/examples/include" # Set this to an integer value to control # max number of connections from clients into the server. max_connections = nolimit # Normally, yaws does not restrict the number of times a connection is # kept alive using keepalive. Setting this parameter to an integer X # will ensure that connections are closed once they have been used X times. # This can be a useful to guard against long running connections # collecting too much garbage in the Erlang VM. keepalive_maxuses = nolimit # Override the garbage collection option parameters for processes # that handle new connections. Useful for systems expecting long-lived # connections that handle a lot of data. The default value is Erlang's # default. Valid options are {fullsweep_after, X} and/or {min_heap_size, Y} where # X and Y are integers. See Erlang's erlang:spawn_opt/4 function for more # details. The value type is a quoted string containing an Erlang proplist or # the atom undefined. process_options = "[]" # Set the size of the cached acceptor process pool. The value must be an # integer greater than or equal to 0. The default pool size is 8. Setting # the pool size to 0 effectively disables the pool. #acceptor_pool_size = 8 # This is a debug variable, possible values are http | traffic | false # It is also possible to set the trace (possibly to the tty) while # invoking yaws from the shell as in # yaws -i -T -x (see man yaws). trace = false # Enable this if we want to use the old OTP ssl implementation # OTP R13B03 is known to work with this flag set to false (default). use_old_ssl = false # It is possible to have yaws start additional application-specific code at # startup. Set runmod to the name of the module you want yaws to start. It # assumes the module has an exported function start/0. To have multiple # runmods just add more "runmod = xyz" lines. # # runmod = mymodule # By default yaws will copy the erlang error_log and # append it to a wrap log called report.log (in the logdir). # This feature can be turned off. This would typically # be the case when yaws runs within another larger app. copy_error_log = true # Logs are wrap logs log_wrap_size = 1000000 # Possibly resolve all hostnames in logfiles so webalizer # can produce the nice geography piechart log_resolve_hostname = false # Fail completely or not if yaws fails to bind a listen socket. fail_on_bind_err = true # If HTTP auth is used, it is possible to have a specific # auth log. As of release 1.90 the global auth_log is # deprecated and ignored. Now, this variable must be set in # server part #auth_log = true # When we're running multiple yaws systems on the same # host, we need to give each yaws system an individual # name. Yaws will write a number of runtime files under # ${HOME}/.yaws/yaws/${id} # The default value is "default" # If we're not planning to run multiple webservers on the # same host it's much better to leave this value unset since # then all the ctl function (--stop et.el) work without having # to supply the id. # # id = myname # Earlier versions of Yaws picked the first virtual host # in a list of hosts with the same IP/PORT when the Host: # header doesn't match any name on any Host. # This is often nice in testing environments but not # acceptable in real-world hosting scenarios; # think http://porn.bigcompany.com pick_first_virthost_on_nomatch = true # If the HTTP client session is to be kept alive, wait this many # milliseconds for a new request before timing out the connection. Note # that infinity is a valid value but it's not recommended. keepalive_timeout = 30000 # Now, a set of virtual servers. # The examples below first show two virthosted servers on the same IP (0.0.0.0) # in this case, but an explicit IP can be given as well. <server localhost> port = 8080 listen = 0.0.0.0 docroot = "%yawsdir%/www" auth_log = true appmods = <cgi-bin, yaws_appmod_cgi> </server> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/win32/img/�������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311413�011213� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/win32/img/yaws_head.gif������������������������������������������������������������������0000664�0001750�0001750�00000004404�12605311413�013570� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a <�Ä��ÿÿÿÿÌÌÿ™™ÿffÿ33ÿ��ÌÌÌÌ™™ÌffÌ33Ì��™™™™��ffff��3333���33���ÿÿÿ������������������������������������!ù��,���� <�@ÿà$Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,¶„bÉl:ŸNˆdJu@¯X§ƒÊ•0 Ù°xL.›Ïè´zÍn³ȸ\¦tÛïø¼~ÏïûÿKp)un[]ShR] b c€P VW‹‡]‰”Ÿ ¡P‚s¥¦&¢ª«¬­®¯h9„gœT“K ‡˜WP¸žK†‡ºO¼Ã•¸Ä ͰÒÓ}§×D�¶ÔÜÝÞß­Ø3 ÍS"µKèó›ÍÈ ÊÍ–œš½Ðè$5ó® A@ H˜`¡Â„´j1œÈð Å‹3æI î�»r Y “ð€Å‚‘èJÿ¦0€rŠJ,q½L A„–Ü1P£ÏŸ@ƒ ýö0á�wHÙ`G.¤Ó§Øb¢TµªÕ†ÚÉçkаgMœ)ÂDJ#²c%ÄS˜Ù±ž¼Fa{e“1Lrê•BLÙÚ'h—l"–·,]­ š^]̸qU©œPuLjVĘ3kv£¸²çÏOÜ1¶1F›S«~ºõ Ñ«cËžÝÁk<ËØäãr¶ïßMH¹>6ðãÈ1Êrq¹ÍnÔYž{rº¥‚�¹”þUoû\|Io‰=9ЉWNe¾½ûV –ŸbϰõÃkêñnR=<à‘ÏŒWu¹½—\|é©§ÿ;¸S F(¡ ¼“ ‚)¤´Â!3•ð€LëÐG‹~(t~ÑTÞ„,¶èâ‹v(„�-LahcK“™dÝ/œƒ ?,ÐÀC>@ä9·y–0ÑdY—L‹wø RVZºð³“b¶e„éd"9‰…/a:0‰j6ÁO^iJIf—PBÙ&>s"v¡|öɘ(ù)h K&Gå{½Á(Æžƒ6êè…**é¤Y÷èSÍQªé¦KØfnÚõ!àu‰rj*–^ê{§¶ £ ™¶K©hàâê­}¤ªjHÆáêk{ò•+$NAký \$¿º¢ë®åDÚì´ª1Z‚ÿ´·à²â‡xÇ@ýôv(oÒỶTPʳК€ºð¦†Þ `;F±ÆfÒI]èh_b€‹"³2à>ÇÆ �´{M¯ GŒQ…rÐgo•è›pÀ¶êÅI©#Ý3êt\r¢¬Ä«Ä×°Ã@p1Ê0"޵ŸT"²ø:£³=s¨€À]t¥OŠÇlQ…|ôSíÅSOFG- G,Å2 � Ó€ 6wÑ�;ÐÒS@ßõKr¿eŒ,õÚl·M†Qa+}õ#%i‡]$ �Þœ�y‰*1%�ß‘ô~n'®øo9·Üs Š’ß*@v_ (uxÂx7@ù {[÷€ÿÝF0ÍÔŒ¨GDÔ®>ɇëçºR¦º«Kä¸ã˜^cä¼ch9.[Ë $á|þáßû ¾Å &SžÕÝ/t¹4qÍ™H¨?#Òeôp¥e.[œ%ÖV€/&"[Äu˜úsŠ•ï”»8#½ø'_Dóòü³ü;.¤ëq ƤëÌ%JW⎕ã 1A Ïpà—Ò‚@ÁmMá˨оèBƒt/þSÁ±hfLá£�…Ž�ªÐ5¬Zœ )ÂÚð†8Ì¡wÈÃúð‡@ ¢‡HÄk ß…%1ÁrŠ]Et§¨Š½ì^üÃÈ6FE A1Š,8bLjªÿOÝ¡[{(WÐȸ©/‚qlŒ£LpEG| ⢠äÆ7b€\ƒ®ð�®üqì¤Týˆ•D:² X㶈õGJj‘Œ¼–%79ŠÔQ <«Õ!Úó­0…‹“˜Ìä8ÉJ&KŸÌ¾ Y¿5ž©Xa¢U.DA(ä¬c–L¥* ØÊ@¾²ÄDè¶¥…Q2ã>¥q&´¤GŒùK0fc¦…ÉÈó‘žªË ÊJèg;#C2î(%l<h‚æ%¾NUÂò›ÆôA½(Y47!’@ݺx*y.‚ò‹efvºUÍMÎËž&H&>g8#$`Ÿi“Ç$8ÑùÿÓdg"[ÏúA0„N ñh Oš¸ yÄ*M‹ÔáHÚQ…Š£ -\ImjÍ}±t 3ZY€ÑŸF#SÐEp.ƒYµ4éÐ’šô£ 5*…’VCõ�à¢pë´*µ†Ämn(�¶ÌöÏÑt¡+è$àS²¾jëê LG‹¾NÄ®]ÄkRصÈpm®`RçØj…BÆu @k(`'KÙ3$¤#ƒ ":ŒG‚ÂRA¨ŠF2ÌF¾i³™å¬¬jWÁêÕ:lÞNð?— À³(AF:w)±ö·€¼,’»×B#á, þç9�€s-L ëväuáÿ¹(RÞñ×_^¸àuERÇÕÌ*Sёٔ‡‚ép%Öeïm­ ¼è.�·ÓÉê ¦W41‘«si~‹Ë´óÚ0s.Ý}\ØÙ”0x¸åd†³ÒMñ¥6L+è·ZjŸñ Z¢\éÒ— %F}å D1ÇáÃfºÞ4ÏÅÎÃzÞ[ÓuæÇÄô!î¦láËøÒR–IlAÆrŒŽí‡d¶´Ogñ\²\žìap€XÄX^‰uÊ1¼ ƒQ¢¿ñ œœ&„q¸l¦l XЂc|œùÂ$s.‰ü ¯¤+Édf²W–h0’ñŃt®Òœtœfó0ˈÆAmñàDó@B†Hlo†ŒMh˜ÎÊxK[.ç{̵{ó=¼A{? Äæ©íèVÇ Âœh´«qPáäŒð;iBb‘ÍÀLMÔ²Çò5^ )l4»Z³N¶zG¢9e÷À›ü]Û•m`Xs!ÅÔÎA,£«igû¸Ä;’¬¿Mîr›ûÜèN·º×Ín"„��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/win32/license.xml������������������������������������������������������������������������0000664�0001750�0001750�00000000746�12605311413�012532� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<license> <issueDate>2008-04-14</issueDate> <licenseSchemaVersion>1.2</licenseSchemaVersion> <licenseType>standard</licenseType> <majorVersion>5</majorVersion> <minorVersion>4</minorVersion> <organization>Claes Wikstrom - Open Source License</organization> <patchVersion>5</patchVersion> <product>BitRock InstallBuilder Multiplatform Enterprise</product> <project>yaws</project> <signature>b0f43380b13adfdb16e2cc2cfa330463</signature> </license> ��������������������������yaws-2.0.2/win32/build.xml.in�����������������������������������������������������������������������0000664�0001750�0001750�00000017564�12605311413�012622� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<project> <shortName>Yaws</shortName> <fullName>Yaws webserver @YAWS_VSN@</fullName> <version>@YAWS_VSN@</version> <installerFilename></installerFilename> <readmeFile></readmeFile> <licenseFile>LICENSE</licenseFile> <splashImage>@abs_srcdir@/img/yaws_head.gif</splashImage> <enableRollback>1</enableRollback> <saveRelativePaths>1</saveRelativePaths> <componentList> <component> <name>default</name> <description>Default Component</description> <canBeEdited>1</canBeEdited> <selected>1</selected> <show>1</show> <folderList> <folder> <description>Program Files</description> <destination>${installdir}</destination> <name>programfiles</name> <platforms>all</platforms> <shortcutList> <shortcut> <comment>Uninstall</comment> <exec>${installdir}/${uninstallerName}</exec> <icon></icon> <name>Uninstall ${product_fullname}</name> <path>${installdir}</path> <platforms>all</platforms> <runInTerminal>0</runInTerminal> <windowsExec>${installdir}/${uninstallerName}.exe</windowsExec> <windowsExecArgs></windowsExecArgs> <windowsIcon></windowsIcon> <windowsPath>${installdir}</windowsPath> </shortcut> </shortcutList> </folder> <folder> <description>Program Files</description> <destination>${installdir}</destination> <name>programfileslinux</name> <platforms>linux</platforms> </folder> <folder> <description>Program Files</description> <destination>${installdir}</destination> <name>programfileswindows</name> <platforms>windows</platforms> <actionList> <logMessage> <text>hello there logging</text> </logMessage> <registrySet> <key>HKEY_LOCAL_MACHINE\SOFTWARE\Hyber\Yaws</key> <name>DIR</name> <type>REG_SZ</type> <value>${installdir}</value> </registrySet> <addDirectoryToPath> <scope>system</scope> <path>${installdir}/bin</path> </addDirectoryToPath> <substitute> <files>${installdir}/yaws.conf</files> <substitutionList> <substitution> <pattern>%yawsdir%</pattern> <value>${installdir}</value> </substitution> </substitutionList> </substitute> </actionList> <distributionFileList> <distributionDirectory> <origin>bin</origin> </distributionDirectory> <distributionDirectory> <origin>logs</origin> </distributionDirectory> <distributionDirectory> <origin>include</origin> </distributionDirectory> <distributionDirectory> <origin>ssl</origin> </distributionDirectory> <distributionDirectory> <origin>doc</origin> </distributionDirectory> <distributionDirectory> <origin>ebin</origin> </distributionDirectory> <distributionDirectory> <origin>www</origin> </distributionDirectory> <distributionDirectory> <origin>applications</origin> </distributionDirectory> <distributionDirectory> <origin>priv</origin> </distributionDirectory> <distributionFile> <origin>LICENSE</origin> </distributionFile> <distributionFile> <origin>yaws.conf</origin> </distributionFile> <distributionFile> <origin>README.txt</origin> </distributionFile> <!-- distributionFile> <origin>include.mk</origin> </distributionFile --> <distributionFile> <origin>vsn.mk</origin> </distributionFile> <!-- distributionDirectory> <origin>src</origin> </distributionDirectory --> <distributionDirectory> <origin>examples</origin> </distributionDirectory> </distributionFileList> </folder> </folderList> <startMenuShortcutList> <startMenuShortcut> <comment>Docs</comment> <name>Docs</name> <runInTerminal>0</runInTerminal> <windowsExec>${installdir}/doc</windowsExec> <windowsExecArgs></windowsExecArgs> <windowsIcon></windowsIcon> <windowsPath>${installdir}/doc</windowsPath> </startMenuShortcut> <startMenuShortcut> <comment>README</comment> <name>README</name> <runInTerminal>0</runInTerminal> <windowsExec>${installdir}/README.txt</windowsExec> <windowsExecArgs></windowsExecArgs> <windowsIcon></windowsIcon> <windowsPath>${installdir}/</windowsPath> </startMenuShortcut> </startMenuShortcutList> </component> </componentList> <parameterList> <directoryParameter> <name>installdir</name> <description>Installer.Parameter.installdir.description</description> <explanation>Installer.Parameter.installdir.explanation</explanation> <value>${platform_install_prefix}/${product_shortname}-${product_version}</value> <default>${platform_install_prefix}/${product_shortname}-${product_version}</default> <allowEmptyValue>0</allowEmptyValue> <ask>yes</ask> <cliOptionName>prefix</cliOptionName> <mustBeWritable>yes</mustBeWritable> <mustExist>0</mustExist> <width>30</width> </directoryParameter> </parameterList> <finalPageActionList> <actionGroup progressText="${msg(Installer.ReadmeFile.View)}"> <actionList> <readFile path="${installdir}/README.txt" name="languageFileText" encoding="iso8859-1"/> <showText text="${languageFileText}" title="${msg(Installer.ReadmeFile.Title)}"/> </actionList> </actionGroup> </finalPageActionList> </project> ��������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/win32/README.developer�������������������������������������������������������������������0000664�0001750�0001750�00000001451�12605311413�013224� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������To cross-compile Yaws for windows, we need to install mingw32 compiler then run the configure script with --host option: $> ./configure --host i586-mingw32msvc && make To create an installer, we need a copy of the install-builder. Since yaws is an open source project. We have a free license of bitrock installer. Download the bitrock installer and install it somewhere (http://www.bitrock.com/download_installbuilder_download.html), Then run: $> make mkinstaller INSTALL_BUILDER=/path/to/installbuilder By default INSTALL_BUILDER variable points on '${HOME}/installbuilder-5.4.14'. Here, 'mkinstaller' target will use a distribution directory to build Yaws installer, so you don't need to run configure script with --host option. This will produce the installer 'Yaws-{VSN}-windows-installer.exe' �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/win32/README.txt�������������������������������������������������������������������������0000664�0001750�0001750�00000000670�12605311413�012060� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ win32 version of yaws For just running yaws, it works pretty much the same as on UNIX. Commands that don't work are --id, --heart and some more Try yaws --help for available options. Just starting > yaws -i Starts a basic yaws system with a yaws.conf taken from the install dir. It's actually possible to develop and edit yaws inside windows. Required tools are unxutils and perl installed. Enjoy, /klacke ������������������������������������������������������������������������yaws-2.0.2/win32/yaws.c�����������������������������������������������������������������������������0000664�0001750�0001750�00000017550�12605311413�011516� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* win32 version of yaws starup script */ /* Author: klacke@hyber.org (Jan 2009) */ #include <windows.h> #include <stdio.h> #define BSIZ 16000 static unsigned char path[BSIZ]; static unsigned char *fpath; static void readreg() { HKEY hKey; DWORD bsz = BSIZ; // Check where yaws is installed, we need to -pa that path if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Hyber\\Yaws", 0, KEY_READ, &hKey) != ERROR_SUCCESS) { printf ("Cannot find yaws installation in the registry\n"); exit(1); } memset(path, 0, BSIZ); /*int ret = */RegQueryValueEx(hKey, "DIR", NULL, NULL, path, &bsz); fpath = (unsigned char*)malloc(strlen((char*)path)); int i; for(i = 0; i<strlen((char*)path); i++ ) { if (path[i] == '\\') { fpath[i] = '/'; } else fpath[i] = path[i]; } fpath[i] = 0; } int charg(char **argv, char *s1, char *s2, int p) { if (strcmp(s1, argv[p]) == 0) return 1; if ((s2 != NULL) && strcmp(s2, argv[p]) == 0) return 1; return 0; } int runwait(char *execString) { STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; //printf("execString: %s \n", execString); if(CreateProcess(0, execString, NULL, NULL, FALSE, 0, 0, 0, &si, &pi)) { unsigned long ret = 0; // wait for process to finish WaitForSingleObject(pi.hProcess, INFINITE); if (GetExitCodeProcess(pi.hProcess, &ret) == 0) ret = 1; CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return ret; } printf("Failed to create the process entirely\n"); printf("Tried to invoke: <%s> \n", execString); printf("Make sure you have <erl> in your environment PATH \n"); return 1; } int nosh(char *s) { char buf[BUFSIZ]; sprintf (buf, "erl -noshell -pa \"%s/ebin\" %s ", fpath, s); return runwait(buf); } int help() { printf("usage: " "" " yaws -i | --interactive -- interactive (no daemon) mode" " yaws -w | --winteractive -- interactive (werl) " " yaws --daemon -- daemon mode" "" "" "" " Auxiliary flags for the daemon: " " --id Id -- set system id" " --debug -- debug mode " " --conf File -- set config file" " --tracetraf -- trace traffic" " --tracehttp -- trace http traffic" " --traceout -- trace output to stdout" " --version -- print version" " --pa path -- add load path" " --mnesiadir dir -- start Mnesia in dir" " --sname xxx -- start with sname xxx" " --name xxx -- start with name xxx" " --runmod mod -- call mod:start/0 at startup" " --erlarg X -- pass argument X to $erl" "" "ctl functions ... " " yaws --hup [--id ID] -- hup the daemon, reload conf" " yaws --stop [--id ID] -- stop the daemon " " yaws --debug-dump [--id ID] -- produce a debug dump " " yaws --status [--id ID] -- query the daemon status " " yaws --load Modules -- load modules " " yaws --ls -- list Yaws nodes and their status" " yaws --ctltrace traffic|http -- toggle trace of running daemon"); return(0); } int main(int argc, char**argv) { int interactive = 1; int winteractive = 0; int daemon = 0; char *conf = NULL; char *sname = NULL; char *name = NULL; int debug = 0; char *runmod = NULL; char *trace = NULL; char *traceoutput = NULL; char tbuf[BUFSIZ]; char paBuf[BUFSIZ]; char execString[BSIZ]; char mnesia[255]; char erlarg[255]; char *id = "default"; memset(paBuf, 0, BUFSIZ); memset(tbuf, 0, BUFSIZ); memset(execString, 0, BSIZ); readreg(); sprintf(paBuf, " -pa \"%s/ebin\" ", fpath); int p = 1; while (p < argc) { if (charg(argv, "-i", "--interactive", p)) { interactive = 1; } else if (charg(argv, "-w", "--winteractive", p)) { winteractive = 1; } else if (charg(argv, "-D", "--daemon", p)) { interactive = winteractive = 0; daemon = 1; } else if (charg(argv, "--debug", NULL, p)) { debug = 1; } else if (charg(argv, "-t", "--tracetraf", p)) { trace=" -yaws trace traffic "; } else if (charg(argv, "-T", "--tracehttp", p)) { trace=" -yaws trace http "; } else if (charg(argv, "-x", "--traceout", p)) { traceoutput = " -yaws traceoutput "; } else if (charg(argv, "--trace", NULL, p)) { traceoutput = " -yaws traceoutput "; trace = " -yaws trace traffic "; } else if (charg(argv, "--mnesiadir", "-M", p)) { sprintf(mnesia, "-mnesia dir \"%s\" -run mnesia start ",argv[++p]); } else if (charg(argv, "-c", "--conf", p)) { conf = argv[++p]; } else if (charg(argv, "--id", NULL, p)) { id = argv[++p]; } else if (charg(argv, "-pa", NULL, p)) { sprintf(tbuf, " -pa \"%s\" ", argv[++p]); strcat(paBuf, tbuf); } else if (charg(argv, "--runmod", "-r", p)) { runmod = argv[++p]; } else if (charg(argv, "--hup", "-h", p)) { return nosh("-s yaws_ctl hup default"); } else if (charg(argv, "--stop", "-s", p)) { return nosh("-s yaws_ctl stop default"); } else if (charg(argv, "--status", "-S", p)) { return nosh("-s yaws_ctl status default"); } else if (charg(argv, "--debug-dump", NULL, p)) { return nosh("-s yaws_ctl debug_dump default "); } else if (charg(argv, "--version", "-v", p)) { nosh("-s yaws printversion"); exit(0); } else if (charg(argv, "--sname", "-sname", p)) { sname = argv[++p]; } else if (charg(argv, "--name", "-name", p)) { name = argv[++p]; } else if (charg(argv, "--erlarg", "-erlarg", p)) { sprintf(tbuf, " %s ", argv[++p]); strcat(erlarg, tbuf); } else { return help(); } p++; } if (winteractive) sprintf(execString, "werl.exe %s %s ", erlarg, paBuf); else sprintf(execString, "erl.exe %s %s ", erlarg, paBuf); if (debug) strcat(execString, " -boot start_sasl -yaws debug "); if ((interactive == 0 && winteractive == 0) || daemon == 1) strcat(execString, " -detached "); if (conf == NULL) sprintf(tbuf, " -conf \"%s\\yaws.conf\" ", path); else sprintf(tbuf, " -conf \"%s\" ", conf); strcat(execString, tbuf); strcat(execString, " -run yaws -yaws id default "); if (mnesia != NULL) strcat(execString, mnesia); if (trace != NULL) strcat(execString, trace); if (traceoutput != NULL) strcat(execString, traceoutput); if (sname != NULL) { sprintf(tbuf," -sname %s ", sname); strcat(execString, tbuf); } else if (name != NULL) { sprintf(tbuf, " -name %s ", name); strcat(execString, tbuf); } if (runmod != NULL) { sprintf(tbuf, " -runmod %s ", runmod); strcat(execString, tbuf); } return runwait(execString); } ��������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/win32/Makefile.am������������������������������������������������������������������������0000664�0001750�0001750�00000002752�12605311413�012421� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## ## Debian Linux mingw cross-compiler version: ## To install # sudo apt-get install mingw32 EXTRA_DIST = README.txt README.developer license.xml \ yaws.conf img # TODO: replace .sh and yaws.conf bin_PROGRAMS = yaws yaws_CFLAGS = $(EXTRAINCLUDE) yaws_LDFLAGS = yaws_LDADD = yaws_SOURCES = yaws.c install-data-local: $(AM_V_at)$(INSTALL) -m 644 @srcdir@/yaws.conf $(DESTDIR)$(yawsdir) $(AM_V_at)$(INSTALL) -m 644 @srcdir@/README.txt $(DESTDIR)$(yawsdir) $(AM_V_at)$(INSTALL) -m 644 @top_srcdir@/vsn.mk $(DESTDIR)$(yawsdir) $(AM_V_at)$(INSTALL) -m 644 @top_srcdir@/LICENSE $(DESTDIR)$(yawsdir) $(AM_V_at)cp -r @top_srcdir@/ssl $(DESTDIR)$(yawsdir) uninstall-local: $(AM_V_at)rm -fr $(DESTDIR)$(yawsdir)/ssl $(AM_V_at)rm -f $(DESTDIR)$(yawsdir)/yaws.conf \ $(DESTDIR)$(yawsdir)/README.txt \ $(DESTDIR)$(yawsdir)/LICENSE \ $(DESTDIR)$(yawsdir)/vsn.mk mkinstaller: install $(AM_V_at)[ -n $(UNIX2DOS) ] && CONV=$(UNIX2DOS) || CONV=$(TODOS); \ $${CONV} $(DESTDIR)$(yawsdir)/LICENSE 2>/dev/null; \ for ext in txt erl conf html yaws js pem; do \ find $(DESTDIR)$(yawsdir) -name "*.$${ext}" -exec $${CONV} {} \; 2>/dev/null;\ done $(AM_V_at)$(INSTALL) -m 644 @builddir@/build.xml $(DESTDIR)$(yawsdir) $(AM_V_at)(cd $(DESTDIR)$(yawsdir) && $(INSTALL_BUILDER)/bin/builder build build.xml windows) $(AM_V_at)mv $(INSTALL_BUILDER)/output/*.exe @top_srcdir@ $(AM_V_at)rm -f $(DESTDIR)$(yawsdir)/build.xml # Local Variables: # tab-width: 8 # End: ����������������������yaws-2.0.2/man/�������������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312015�010247� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/man/Makefile.in��������������������������������������������������������������������������0000664�0001750�0001750�00000040451�12605311446�012247� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = man DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MANPAGES = yaws.1 yaws.conf.5 yaws_api.5 yaws_soap_lib.5 PDFS = $(MANPAGES:=.pdf) EXTRA_DIST = $(MANPAGES) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign man/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @MINGW_FALSE@clean-local: @MINGW_FALSE@pdf-local: clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: pdf-local ps: ps-am ps-am: uninstall-am: uninstall-local .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am pdf-local ps ps-am tags-am \ uninstall uninstall-am uninstall-local @MINGW_FALSE@install-data-local: @MINGW_FALSE@ $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(mandir)/man1 @MINGW_FALSE@ $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(mandir)/man5 @MINGW_FALSE@ $(AM_V_at)$(INSTALL) -m 644 @srcdir@/yaws.1 $(DESTDIR)$(mandir)/man1 @MINGW_FALSE@ $(AM_V_at)$(INSTALL) -m 644 @srcdir@/yaws.conf.5 $(DESTDIR)$(mandir)/man5 @MINGW_FALSE@ $(AM_V_at)$(INSTALL) -m 644 @srcdir@/yaws_api.5 $(DESTDIR)$(mandir)/man5 @MINGW_FALSE@ $(AM_V_at)$(INSTALL) -m 644 @srcdir@/yaws_soap_lib.5 $(DESTDIR)$(mandir)/man5 @MINGW_FALSE@uninstall-local: @MINGW_FALSE@ $(AM_V_at)rm -f $(DESTDIR)$(mandir)/man1/yaws.1 @MINGW_FALSE@ $(AM_V_at)rm -f $(DESTDIR)$(mandir)/man5/yaws.conf.5 @MINGW_FALSE@ $(AM_V_at)rm -f $(DESTDIR)$(mandir)/man5/yaws_api.5 @MINGW_FALSE@ $(AM_V_at)rm -f $(DESTDIR)$(mandir)/man5/yaws_soap_lib.5 @MINGW_TRUE@install-data-local: pdf @MINGW_TRUE@ $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(mandir) @MINGW_TRUE@ $(AM_V_at)$(INSTALL) -m 644 yaws.1.pdf $(DESTDIR)$(mandir) @MINGW_TRUE@ $(AM_V_at)$(INSTALL) -m 644 yaws.conf.5.pdf $(DESTDIR)$(mandir) @MINGW_TRUE@ $(AM_V_at)$(INSTALL) -m 644 yaws_api.5.pdf $(DESTDIR)$(mandir) @MINGW_TRUE@ $(AM_V_at)$(INSTALL) -m 644 yaws_soap_lib.5.pdf $(DESTDIR)$(mandir) @MINGW_TRUE@uninstall-local: @MINGW_TRUE@ $(AM_V_at)rm -f $(DESTDIR)$(mandir)/yaws.1.pdf @MINGW_TRUE@ $(AM_V_at)rm -f $(DESTDIR)$(mandir)/yaws.conf.5.pdf @MINGW_TRUE@ $(AM_V_at)rm -f $(DESTDIR)$(mandir)/yaws_api.5.pdf @MINGW_TRUE@ $(AM_V_at)rm -f $(DESTDIR)$(mandir)/yaws_soap_lib.5.pdf @MINGW_TRUE@pdf-local: $(PDFS) @MINGW_TRUE@%.pdf: % @MINGW_TRUE@ $(AM_V_GEN)$(MAN) -t $< 2>/dev/null | $(PS2PDF) - $@; @MINGW_TRUE@clean-local: @MINGW_TRUE@ $(AM_V_at)rm -f $(PDFS) # Local Variables: # tab-width: 8 # End: # 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: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/man/yaws_api.5���������������������������������������������������������������������������0000664�0001750�0001750�00000076647�12605311412�012115� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH YAWS_API "5" "" "" "User API" -*- nroff -*- .SH NAME yaws_api \- api available to yaws web server programmers .SH SYNOPSIS .B yaws_api:Function(...) .SH DESCRIPTION .PP This is the api available to yaws web server programmers. The Erlang module yaws_api contains a wide variety of functions that can be used inside yaws pages. .PP Each chunk of yaws code is executed while the yaws page is being delivered from the server. We give a very simple example here to show the basic idea. Imagine the following HTML code: \fI .nf <html> <body> <h1> Header 1</h1> <erl> out(Arg) -> {html, "<p> Insert this text into the document"}. </erl> </body> </html> .fi \fR .PP The \fBout(Arg)\fR function is supplied one argument, an #arg{} structure. We have the following relevant record definitions: \fI .nf -record(arg, { clisock, % the socket leading to the peer client client_ip_port, % {ClientIp, ClientPort} tuple headers, % headers req, % request orig_req, % original request clidata, % The client data (as a binary in POST requests) server_path, % The normalized server path % (pre-querystring part of URI) querydata, % For URIs of the form ...?querydata % equiv of cgi QUERY_STRING appmoddata, % (deprecated - use pathinfo instead) the remainder % of the path leading up to the query docroot, % Physical base location of data for this request docroot_mount, % virtual directory e.g /myapp/ that the docroot % refers to. fullpath, % full deep path to yaws file cont, % Continuation for chunked multipart uploads state, % State for use by users of the out/1 callback pid, % pid of the yaws worker process opaque, % useful to pass static data appmod_prepath, % (deprecated - use prepath instead) path in front % of: <appmod><appmoddata> prepath, % Path prior to 'dynamic' segment of URI. % ie http://some.host/<prepath>/<script-point>/d/e % where <script-point> is an appmod mount point, % or .yaws,.php,.cgi,.fcgi etc script file. pathinfo % Set to '/d/e' when calling c.yaws for the request % http://some.host/a/b/c.yaws/d/e % equiv of cgi PATH_INFO }). .fi \fR The headers argument is also a record: \fI .nf -record(headers, { connection, accept, host, if_modified_since, if_match, if_none_match, if_range, if_unmodified_since, range, referer, user_agent, accept_ranges, cookie = [], keep_alive, location, content_length, content_type, content_encoding, authorization, transfer_encoding, x_forwarded_for, other = [] % misc other headers }). .fi \fR .PP The \fBout/1\fR function can use the Arg to generate any content it likes. We have the following functions to aid that generation. .SH API .TP \fBssi(DocRoot, ListOfFiles)\fR Server side include. Just include the files as is in the document. The files will \fBnot\fR be parsed and searched for <erl> tags. .TP \fBpre_ssi_files(DocRoot, ListOfFiles) -> Server side include of pre-indented code. The data in Files will be included but contained in a <pre> tag. The data will be htmlized. .TP \fBpre_ssi_string(String)\fR Include htmlized content from String. .TP \fBf(Fmt, Args)\fR The equivalent of io_lib:format/2. This function is automatically -included in all erlang code which is a part of a yaws page. .TP \fBhtmlize(Binary | List | Char)\fR Htmlize an IO list object. .TP \fBset_cookie(Name, Value, Options])\fR Sets a cookie to the browser. Options are: \fI .nf {expires, UtcTime} - Cookie expiration time, where UtcTime is a tuple returned by calendar:universal_time/0. {max_age, Age} - Defines the lifetime of the cookie, in seconds, where age is an integer >= 0. {path, Path} - Path is a string that specifies the subset of URLs to which this cookie applies. {domain, Domain} - Domain is a string that specifies the domain for which the cookie is valid. {comment, Comment} - Comment is a string that doccuments the server's intended use of the cookie. secure - Directs the user agent to use only secure means to contact the origin server whenever it sends back this cookie. http_only - Restricts cookie access from other non-HTTP APIs. .fi \fR .TP \fBsetcookie(Name, Value, [Path, [ Expire, [Domain , [Secure]]]])\fR Sets a cookie to the browser. This function is deprecated by set_cookie/3. .TP \fBfind_cookie_val(Cookie, Header)\fR This function can be used to search for a cookie that was previously set by \fBsetcookie/2-6\fR. For example if we set a cookie as \fByaws_api:setcookie("sid",SomeRandomSid)\fR, then on subsequent requests from the browser we can call: \fBfind_cookie("sid",(Arg#arg.headers)#headers.cookie)\fR The function returns [] if no cookie was found, otherwise the actual cookie is returned as a string. .TP \fBparse_set_cookie(Str)\fR This function parses the value of a \fBSet-Cookie\fR header, following the RFC6265. Because old RFCs (2109 and 2965) are still used, it is backward compatible. So this function returns a \fI#setcookie{}\fR record when only one cookie is found. If multiple cookies are set in a single \fBSet-Cookie\fR header, it returns a list of \fI#setcookie{}\fR records. If no cookie was found or if an error occurred, it returns []. \fI#setcookie{}\fR record is defined in \fIyaws_api.hrl\fR: \fI .nf -record(setcookie, {key, value, quoted = false, domain, max_age, expires, path, secure = false, http_only = false, extensions = []}). .fi \fR .TP \fBparse_cookie(Str)\fR This function parses the value of \fBCookie\fR header, following the RFC6265. It returns a list of \fI#cookie{}\fR records. If no cookie was found or if an error occurred, it returns []. \fI#cookie{}\fR record is defined in \fIyaws_api.hrl\fR: \fI .nf -record(cookie, {key, value, quoted = false}). .fi \fR .TP \fBformat_set_cookie(SetCookie)\fR Build a cookie string from a \fI#setcookie{}\fR record like returned by \fBparse_set_cookie/1\fR. .TP \fBformat_cookie(Cookie | [Cookie])\fR Build a cookie string from a \fI#cookie{}\fR record (or a list or records) like returned by \fBparse_cookie/1\fR. .TP \fBredirect(Url)\fR This function generates a redirect to the browser. It will clear any previously set headers. So to generate a redirect \fBand\fR set a cookie, we need to set the cookie after the redirect as in: \fI .nf out(Arg) -> ... do some stuff Ret = [{redirect, "http://www.somewhere.com"}, setcookie("sid", Random) ]. .fi \fR .TP \fBredirect_self(Arg)\fR If we want to issue a redirect to ourselves, this function is useful. It returns a record \fI#redir_self{}\fR defined in \fIyaws_api.hrl\fR. The record contains fields to construct a URL to ourselves. \fI .nf -record(redir_self, { host, % string() - our own host scheme, % http | https scheme_str, % "https://" | "http://" port, % integer() - our own port port_str % "" | ":<int>" - the optional port part % to append to the url }). .fi .TP \fBget_line(String)\fR This function is convenient when getting \\r\\n terminated lines from a stream of data. It returns: \fB{line, Line, Tail}\fR or \fB{lastline, Line, Tail}\fR The function handles multilines as defined in e.g. SMTP or HTTP .TP \fBmime_type(Scope, FileName)\fR Returns the MIME type as defined by the extension of \fIFileName\fR. \fIScope\fR can have following values: .RS 12 \fBglobal\fR - returns the result obtained from the global context. .br \fB#sconf{} | {ServerName, Port}\fR - returns the result obtained from the virtual server's context. If no MIME type is found in this scope, it falls back on the global one. .RE .TP \fBmime_type(FileName)\fR Tries to determine the right \fIScope\fR before calling mime_type/2. .TP \fBstream_chunk_deliver(YawsPid, Data)\fR When a yaws function needs to deliver chunks of data which it gets from a process. The other process can call this function to deliver these chunks. It requires the \fBout/1\fR function to return the value \fB{streamcontent, MimeType, FirstChunk}\fR to work. YawsPid is the process identifier of the yaws process delivering the original .yaws file. That is self() in the yaws code. The Pid must typically be passed (somehow) to the producer of the stream. .TP \fBstream_chunk_deliver_blocking(YawsPid, Data)\fR A synchronous version of the above function. This synchronous version must always be used when the producer of the stream is faster than the consumer. This is usually the case since the client is the WWW browser. .TP \fBstream_chunk_end(YawsPid)\fR When the process discussed above is done delivering data, it must call this function to let the yaws content delivering process finish up the HTTP transaction. .TP \fBstream_process_deliver(Socket, IoList)\fR Yaws allows application processes to deliver data directly to the client. The application tells yaws about such a process by returning \fB{streamcontent_from_pid, MimeType, Pid}\fR from its \fBout/1\fR function. In this case, \fIPid\fR uses the \fBstream_process_deliver/2\fR function to deliver data to the client. The application gets \fISocket\fR from \fIArg#arg.clisock\fR, and \fIIoList\fR is the data to be sent to the client. .TP \fBstream_process_deliver_chunk(Socket, IoList)\fR Same as above but delivers \fIIoList\fR using HTTP chunked transfer format. \fIIoList\fR must have a size greater than zero. The application process delivering the data will have had to have make sure that the HTTP headers of the response indicate chunked transfer mode, either by ensuring no Content-Length header is set or by specifically setting the Transfer-Encoding header to chunked. .TP \fBstream_process_deliver_final_chunk(Socket, IoList)\fR If the application process delivering data to the client uses chunked transfer mode, it must call this to deliver the final chunk of the transfer. This tells yaws to create a special final chunk in the format required by the HTTP specification (RFC 2616). \fIIoList\fR may be empty, but if its size is greater than zero, that data will be sent as a separate chunk before the final chunk. .TP \fBstream_process_end(Socket, YawsPid)\fR Application processes delivering data directly to clients must call this function to inform yaws that they've finished using \fISocket\fR. The \fIYawsPid\fR argument will have been passed to the process earlier when yaws sent it a message telling it to proceed with data delivery. Yaws expects \fISocket\fR to be open. .TP \fBstream_process_end(closed, YawsPid)\fR Same as the previous function but the application calls this if it closes the client socket as part of its data delivery process. This allows yaws to continue without assuming the socket is still open and encountering errors due to that assumption. The \fIYawsPid\fR argument will have been passed to the application process earlier when yaws sent it a message telling it to proceed with data delivery. .TP \fBparse_query(Arg)\fR This function will parse the query part of the URL. It will return a {Key, Value} list. .TP \fBqueryvar(Arg, VarName)\fR This function is automatically included from yaws_api in all .yaws pages. It is used to search for a variable in the querypart of the url. Returns {ok, Val} or undefined. If a variable is defined multiple times, the function may also return \fI{Val1, Val2...}\fR. .TP \fBparse_post(Arg)\fR If the browser has set the Content-Type header to the value "application/x-www-form-urlencoded", this function will parse the request's body. It will return a {Key, Value} list. .TP \fBpostvar(Arg, VarName)\fR This function is automatically included from yaws_api in all .yaws pages. It is used to search for a variable in the request's body sent by the client. Returns {ok, Val} or undefined. If a variable is defined multiple times, the function may also return \fI{Val1, Val2...}\fR. .TP \fBgetvar(Arg, VarName)\fR This function is used to search a variable in the query part of the URL and in the request's body. it invokes queryvar/2 and postvar/2 and merges the results. .TP \fBparse_multipart_post(Arg)\fR If the browser has set the Content-Type header to the value "multipart/form-data", which is the case when the browser wants to upload a file to the server the following happens: If the function returns \fB{result, Res}\fR no more data will come from the browser. If the function returns \fB{cont, Cont, Res}\fR the browser will supply more data. (The file was too big to come in one read) This indicates that there is more data to come and the out/1 function should return {get_more, Cont, User_state} where User_state might usefully be a File Descriptor. The Res value is a list of either: \fB{head, {Name, Headers}}\fR | \fB{part_body, Binary}\fR | \fB{body, Binary}\fR The function returns \fB{error, Reason}\fR when an error occurred during the parsing. Example usage could be: \fI .nf <erl> out(A) -> case yaws_api:parse_multipart_post(A) of {cont, Cont, Res} -> St = handle_res(A, Res), {get_more, Cont, St}; {result, Res} -> handle_res(A, Res), {html, f("<pre>Done </pre>",[])}; {error, Reason} -> {html, f("An error occured: ~p", [Reason])} end. handle_res(A, [{head, {Name, _Hdrs}}|T]) -> io:format("head:~p~n",[Name]), handle_res(A, T); handle_res(A, [{part_body, Data}|T]) -> io:format("part_body:~p~n",[Data]), handle_res(A, T); handle_res(A, [{body, Data}|T]) -> io:format("body:~p~n",[Data]), handle_res(A, T); handle_res(A, []) -> io:format("End_res~n"). </erl> .fi \fR .TP \fBnew_cookie_session(Opaque)\fR Create a new cookie based session, the yaws system will set the cookie. The new random generated cookie is returned from this function. The Opaque argument will typically contain user data such as user name and password .TP \fBnew_cookie_session(Opaque, TTL)\fR As above, but allows to set a session specific time-out value, overriding the system specified time-out value. .TP \fBnew_cookie_session(Opaque, TTL, CleanupPid)\fR As above, but also sends a message \fI{yaws_session_end, Reason, Cookie, Opaque}\fR to the provided CleanuPid where Reason can be either of \fItimeout\fR or \fInormal\fR. The \fICookie\fR is the HTTP cookie as returned by \fInew_session()\fR and the Opaque is the user provided Opaque parameter to \fInew_session()\fR. The purpose of the feature is to cleanup resources assigned to the session. .TP \fBcookieval_to_opaque(CookieVal)\fR .TP \fBprint_cookie_sessions() \fR .TP \fBreplace_cookie_session(Cookie, NewOpaque)\fR .TP \fBdelete_cookie_session(Cookie)\fR .TP \fBsetconf(Gconf, Groups)\fR This function is intended for embedded mode in yaws. It makes it possible to load a yaws configuration from another data source than /etc/yaws.conf, such as a database. If yaws is started with the environment \fI{embedded, true}\fR, yaws will start with an empty default configuration, and wait for some other program to execute a \fIsetconf/2\fR The Gconf is a \fI#gconf{}\fR record and the Group variable is a list of lists of \fI#sconf{}\fR records. Each sublist must contain \fI#sconf{}\fR records with the same IP/Port listen address. To create a suitable initial #gconf{} record see the code in yaws_config:make_default_gconf/2. Especially the \fIyaws_dir\fR parameter is important to get right. .TP \fBurl_decode(Str)\fR Decode url-encoded string. A URL encoded string is a string where all alfa numeric characters and the the character _ are preserved and all other characters are encode as "%XY" where X and Y are the hex values of the least respective most significant 4 bits in the 8 bit character. .TP \fBurl_encode(Str)\fR Url-encodes a string. All URLs in HTML documents must be URL encoded. .TP \fBget_sslsocket(Socket)\fR Returns a socket for SSL sockets or the atom \fIundefined\fR for non-SSL sockets. Useful for applications that have to deal with both SSL and non-SSL sockets. .TP \fBget_listen_port(Sconf)\fR Return the actual port number used by the listen socket of the virtual server indicated by the function argument, an \fI#sconf{}\fR record instance. If successful, returns the requested port number, or returns \fI{error, not_found}\fR if the function argument does not match any known virtual server. This function is useful for retrieving the actual port number when, e.g. for testing purposes, a virtual server is configured to use port 0, which will cause it to have an ephemeral port assigned by the operating system. .TP \fBreformat_header(H)\fR Returns a list of reformatted header values from a #headers{} record. The return list is suitable for retransmit. .TP \fBreformat_header(H, FormatFun)\fR Returns a list of reformatted header values from a #headers{} record, with each element of the list formatted via a call to \fIFormatFun\fR. This enables converting #headers{} records into various lists of headers and their values. Note that sometimes the \fISet-Cookie\fR header will contain a tuple value of the form \fI{multi, ValueList}\fR \[em] see \fImerge_header/2\fR below for details \[em] so formatting functions should be prepared to handle such a tuple. They should handle it by formatting each member of \fIValueList\fR as a separate \fISet-Cookie\fR header, then returning all such header-value pairs in a list. Note that this implies that sometimes the return values of \fIreformat_header/1\fR and \fIreformat_header/2\fR can be a multi-level list. The \fI{multi, ValueList}\fR construct results only from calls to \fImerge_header/2\fR or \fImerge_header/3\fR, where multiple values are set in separate calls for the same header. .TP \fBset_header(Headers, {Header, Value})\fR Sets header \fIHeader\fR with value \fIValue\fR in the #headers{} record \fIHeaders\fR, and returns a new #headers{} record. Using the atom \fIundefined\fR for \fIValue\fR effectively deletes the header, same as \fIdelete_header/2\fR. .TP \fBset_header(Headers, Header, Value)\fR Same as \fIset_header/2\fR above, except \fIHeader\fR and \fIValue\fR are not passed in a tuple. .TP \fBmerge_header(Headers, {Header, Value})\fR Merges value \fIValue\fR for header \fIHeader\fR with any existing value for that header in the #headers{} record \fIHeaders\fR, and returns a new #headers{} record. Using the atom \fIundefined\fR for \fIValue\fR simply returns \fIHeaders\fR. Otherwise, \fIValue\fR is merged with any existing value already present in the \fIHeaders\fR record for header \fIHeader\fR, comma-separated from that existing value. If no such value exists in the \fIHeaders\fR record, the effect is the same as \fIset_header/2\fR. Note that for the \fISet-Cookie\fR header, values are not comma-separated but are instead collected into a tuple \fI{multi, ValueList}\fR where \fIValueList\fR is the collection of \fISet-Cookie\fR values. This implies that any formatting fun passed to \fIreformat_header/2\fR must be prepared to handle such tuples. .TP \fBmerge_header(Headers, Header, Value)\fR Same as \fImerge_header/2\fR above, except \fIHeader\fR and \fIValue\fR are not passed in a tuple. .TP \fBget_header(Headers, Header)\fR Gets the value of header \fIHeader\fR from the #headers{} record \fIHeaders\fR and returns it. If the header isn't set, the atom \fIundefined\fR is returned. .TP \fBdelete_header(Headers, Header)\fR Deletes any value set for header \fIHeader\fR in the #headers{} record \fIHeaders\fR, and returns a new #headers{} record. .TP \fBrequest_url(ARG)\fR Return the url as requested by the client. Return value is a #url{} record as defined in yaws_api.hrl .TP \fBparse_url(Str)\fR Parse URL in a string, returns a #url record .TP \fBformat_url(UrlRecord)\fR Takes a #url record a formats the Url as a string .TP \fBcall_cgi(Arg, Scriptfilename)\fR Calls an executable CGI script, given by its full path. Used to make `.yaws' wrappers for CGI programs. This function usually returns \fIstreamcontent\fR. .TP \fBcall_cgi(Arg, Exefilename, Scriptfilename)\fR Like before, but calls \fIExefilename\fR to handle the script. The file name of the script is handed to the executable via a CGI meta variable. .TP \fBcall_fcgi_responder(Arg)\fR Calls a FastCGI responder. The address and port of the FastCGI application server are taken from the server configuration (see yaws.conf). Used to make `.yaws' wrappers for FastCGI responders. Returns the same return values as out/1 (see below). .TP \fBcall_fcgi_responder(Arg, Options)\fR Same as above, but Options overrides the defaults from the server configuration: \fI .nf Options = [Option] Option -- one of the following: .fi \fR \fB{app_server_host, string() | ip_address()}\fR The hostname or the IP address of the FastCGI application server. \fB{app_server_port, 0..65535}\fR The TCP port number of the FastCGI application server. \fB{path_info, string()}\fR Override default pathinfo in Arg#arg.pathinfo. \fB{extra_env, ExtraEnv}\fR Extra environment variables to be passed to the FastCGI application server, as a list of name-value pairs. \fI .nf ExtraEnv = [Var] Var = {Name, Value} Name = string() | binary() Value = string() | binary() .fi \fR \fB{trace_protocol, boolean()}\fR Enable or disable tracing of FastCGI protocol messages as info log messages. \fB{log_app_error, boolean()}\fR Enable or disable logging of application error messages: output to stderr and non-zero exit value. .TP \fBcall_fcgi_authorizer(Arg) -> {allowed, Out} | {denied, Out}\fR Calls a FastCGI authorizer. The address and port of the FastCGI application server are taken from the server configuration (see yaws.conf). Used to make `.yaws' wrappers for FastCGI authorizers. Variables contains the values of the variables returned by the FastCGI application server in the "Variable-XXX: YYY" headers. If access is denied, Out contains the complete response returned by the FastCGI application server. This response is typically returned as-is to the HTTP client. If access is allowed, Out contains the response returned by the FastCGI application server minus the body (i.e. minus the content) which should be ignored per the FastCGI specification. This response is typically not returned to the HTTP client. The calling application module may wish to inspect the response, for example by extracting variables (see fcgi_extract_variables below) or by inspecting the headers returned by the FastCGI application server. \fI .nf Out -- See return values for out/1 below .fi \fR .TP \fBcall_fcgi_authorizer(Arg, Options) -> {allowed, Out} | {denied, Out}\fR Same as above, but Options overrides the defaults from the server configuration. See call_fcgi_responder/2 above for a description of Options. .TP \fBfcgi_extract_variables(Out) -> [{Name, Value}]\fR Extracts the environment variables from a FastCGI authorizer response by looking for headers of the form "Variable-Name: Value". \fI .nf Name = string() -- The name of the variable (the "Variable-" prefix has already been removed). Value = string() -- The value of the variable. .fi \fR .TP \fBdir_listing(Arg)\fR Perform a directory listing. Can be used in special directories when we don't want to turn on dir listings for the entire server. Always returns ok. .SH RETURN VALUES from out/1 .PP The out/1 function can return different values to control the behavior of the server. .TP \fB{html, DeepList}\fB This assumes that DeepList is formatted HTML code. The code will be inserted in the page. .TP \fB{ehtml|exhtml, Term}\fR This will transform the erlang term Term into a stream of HTML content. The exhtml variant transforms into strict XHTML code. The basic syntax of Term is \fI .nf EHTML = [EHTML] | {Tag, Attrs, Body} | {Tag, Attrs} | {Tag} | {Module, Fun, [Args]} | fun/0 | binary() | character() Tag = atom() Attrs = [{Key, Value}] Key = atom() Value = string() | binary() | atom() | integer() | float() | {Module, Fun, [Args]} | fun/0 Body = EHTML .fi \fR For example, \fI{p, [], "Howdy"}\fR expands into "<p>Howdy</p>" and \fI .nf {form, [{action, "a.yaws"}], {input, [{type,text}]}} .fi \fR expands into \fI .nf <form action="a.yaws" <input type="text"> </form> .fi \fR It may be more convenient to generate erlang tuples than plain html code. .TP \fB{content, MimeType, Content}\fR This function will make the web server generate different content than HTML. This return value is only allowed in a yaws file which has only one <erl> </erl> part and no html parts at all. .TP \fB{streamcontent, MimeType, FirstChunk}\fR This return value plays the same role as the \fIcontent\fR return value above. However it makes it possible to stream data to the client if the yaws code doesn't have access to all the data in one go. (Typically if a file is very large or if data arrives from back end servers on the network. .TP \fB{streamcontent_with_timeout, MimeType, FirstChunk, Timeout}\fR Similar to above, but with an explicit timeout. The default timeout is 30 secs. I.e if the application fails to deliver data to the Yaws process, the streaming will stop. This is often not the desired behaviour in Comet/Ajax applications. It's possible to provide 'infinity' as timeout. .TP \fB{streamcontent_from_pid, MimeType, Pid}\fR This return value is similar to the \fIstreamcontent\fR return value above. However it makes it possible to stream data to the client directly from an application process to the socket. This approach can be useful for applications that employ long-polling (Comet) techniques, for example, and for applications wanting to avoid buffering data or avoid HTTP chunked mode transfer for streamed data. .TP \fB{streamcontent_with_size, Sz, MimeType, FirstChunk}\fR This return value is similar to the \fIstreamcontent\fR return value above. However it makes it possible to stream data to the client by setting the content length of the response. As the opposite of other ways to stream data, in this case, the response is not chunked encoded. .TP \fB{header, H}\fR Accumulates a HTTP header. The trailing CRNL which is supposed to end all HTTP headers must NOT be added. It is added by the server. The following list of headers are given special treatment. \fI{connection, What}\fR This sets the Connection: header. If \fIWhat\fR is the special value \fI"close"\fR, the connection will be closed once the yaws page is delivered to the client. \fI{server, What}\fR Sets the Server: header. By setting this header, the server's signature will be dynamically overloaded. \fI{location, Url}\fR Sets the Location: header. This header is typically combined with the \fI{status, 302}\fR return value. \fI{cache_control, What}\fR Sets the Cache-Control: header. \fI{expires, What}\fR Sets the Expires: header. \fI{date, What}\fR Sets the Date: header. \fI{allow, What}\fR Sets the Allow: header. \fI{last_modified, What}\fR Sets the Last-Modified: header. \fI{etag, What}\fR Sets the Etag: header. \fI{set_cookie, Cookie}\fR Prepends a Set-Cookie: header to the list of previously set Set-Cookie: headers. \fI{content_range, What}\fR Sets the Content-Range: header. \fI{content_type, MimeType}\fR Sets the Content-Type: header. \fI{content_encoding, What}\fR Sets the Content-Encoding: header. If this header is defined, no deflate is performed by Yaws. So you can compress data by yourself. \fI{content_length, Len}\fR Normally yaws will ship Yaws pages using Transfer-Encoding: chunked. This is because we generally can't know how long a yaws page will be. If we for some reason want to force a Content-Length: header (and we actually do know the length of the content, we can force yaws to not ship the page chunked. \fI{transfer_encoding, What}\fR Sets the Transfer-Encoding: header. \fI{www_authenticate, What}\fR Sets the WWW-Authenticate: header. \fI{vary, What}\fR Sets the Vary: header. All other headers must be added using the normal HTTP syntax. Example: \fI{header, {"My-X-Header", "gadong"}}\fR or \fI{header, "My-X-Header: gadong"}\fR .TP \fB{header, {HeaderName, erase}}\fR Clears the header named \fIHeaderName\fR from the accumulated headers. .TP \fB{allheaders, HeaderList}\fR Will clear all previously accumulated headers and replace them. .TP \fB{status, Code}\fR Will set another HTTP status code than 200. .TP \fBbreak\fR Will stop processing of any consecutive chunks of erl or html code in the yaws file. .TP \fBok\fR Do nothing. .TP \fBflush\fR Flush remaining data sent by the client. .TP \fB{redirect, Url}\fR Erase all previous headers and accumulate a single Location header. Set the status code. .TP \fB{redirect_local, Path}\fR Does a redirect to the same Scheme://Host:Port/Path as we currently are executing in. .TP \fB{get_more, Cont, State}\fR When we are receiving large POSTs we can return this value and be invoked again when more Data arrives. .TP \fB{page, Page}\fR Make Yaws returns a different page than the one being requested. \fIPage\fR is a Request-URI, so it must be url-encoded and can contain a query-string. .TP \fB{page, {Options, Page}}\fR Like the above, but supplying an additional deep list of options. Supported option types are: \fI{status, C}\fR - Set the HTTP response status code \fIC\fR for page \fIPage\fR. \fI{header, H}\fR - Accumulate the HTTP header \fIH\fR for page \fIPage\fR. \fI{disable_cache, Bool}\fR - if set to \fItrue\fR, disable the cache of \fIPage\fR for this call. .TP \fB{ssi, File, Delimiter, Bindings}\fR Server side include File and macro expansion in File. Each occurrence of a string, say "xyz", inside File which is inside Delimiters is replaced with the corresponding value in Bindings. Example: Delimiter = %% File contains the string .... %%xyz%% ..... Bindings contain the tuple {"xyz", "Dingbat"} The occurrence of %%xyz%% in File will be replaced with "Dingbat" in the Server side included output. The {ssi, File, Delimiter, Bindings} statement can also occur inside a deep ehtml structure. .TP \fB{bindings, [{Key1, Value2}, {Key2, Value2} .....]}\fR Establish variable bindings that can be used in the page. All bindings can then be used in the rest of yaws code (in HTML source and within erl tags). In HTML source %%Key%% is expanded to Value and within erl tags \fIyaws_api:binding(Key)\fR can be used to extract Value and \fIyaws_api:binding_exists(Key)\fR can be used to check for the existence of a binding. .TP \fB{yssi, YawsFile}\fR Include a yaws file. Compile it and expand as if it had occured inline. .TP \fB[ListOfValues]\fR It is possible to return a deep list of the above defined return values. Any occurrence of \fIstreamcontent\fR, \fIstreamcontent_with_timeout\fR, \fIstreamcontent_with_size\fR, \fIstreamcontent_from_pid\fR, \fIget_more\fR, \fIpage\fR or \fIbreak\fR in this list is legal only if it is the last position of the list. If not, remaining values in the list are ignored. .SH AUTHOR Written by Claes Wikstrom .SH "SEE ALSO" .BR yaws.conf (5) .BR erl (1) �����������������������������������������������������������������������������������������yaws-2.0.2/man/yaws_soap_lib.5����������������������������������������������������������������������0000664�0001750�0001750�00000006136�12605311412�013116� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH YAWS_SOAP_LIB "5" "" "" "Yaws Soap API" -*- nroff -*- .SH NAME yaws_soap_lib \- api for the yaws soap-functionality .SH SYNOPSIS .B yaws_soap_lib:Function(...) .SH DESCRIPTION .PP This is the Yaws API available for dealing with SOAP. .SH API .TP \fcall(WsdlURL, Operation, ListOfData)\fR This function takes an ('http' or 'file' URL to a WSDL file, an Operation (i.e. Function) to be called and a list of data to that the Operation takes as input argument. Note: that this function makes the assumption that the record used for the body, has the same name as the Operation. For example, if the Operation is named "GetTime", then the record it assumed to be named 'p:GetTime', where 'p' is the default prefix used. .TP \fcall(Wsdl, Operation, ListOfData)\fR Takes a Wsdl structure, as returned from the initModel/1 function, instead of an URL. Else, it works just like the other call/3 function. .TP \fcall(Wsdl, Operation, ListOfData)\fR Takes a Wsdl structure, as returned from the initModel/1 function, instead of an URL. Else, it works just like the other call/3 function. .TP \fcall(Wsdl, Operation, HeaderMsg, BodyMsg)\fR The Wsdl and Operation arguments works just as for the call/3 function. The HeaderMsg and BodyMsg can be either a record, representing a message, or a list of such records. The records can be generated by the write_hrl/2 function. .TP \fcall(Wsdl, Operation, Port, Service, HeaderMsg, BodyMsg)\fR The Wsdl, Operation, HeaderMsg and BodyMsg argument works as for the call/4 function. The Port and Service argument is used for pointing out the particular definitions of the corresponding entries in the WSDl specification used. .TP \fis_wsdl(Wsdl)\fR Returns true if the Wsdl argument is a Wsdl structure, as returned from the initModel/1 function. .TP \fwsdl_model(Wsdl)\fR Returns the Model. .TP \fwsdl_operations(Wsdl)\fR Returns a list of Operations. .TP \fwsdl_op_service(Wsdl)\fR Returns the Service. .TP \fwsdl_op_port(Operation)\fR Returns the port. .TP \fwsdl_op_operation(Operation) -> Op.\fR Returns the operation. .TP \fwsdl_op_binding(Operation) -> Binding.\fR Returns the binding. .TP \fwsdl_op_address(Operation) -> Address.\fR Returns the address. .TP \fwsdl_op_action(Operation)\fR Returns the action. .TP \finitModel(WsdlURL)\fR Takes an URL pointing to an WSDL file. This function will retrieve the file, parse it and return a Wsdl structure that is used as argument to many of the other functions in this module. It will use the default prefix 'p' for the elements/attributes of the target namespace. .TP \finitModel(WsdlURL, Prefix)\fR Works as the initModel/1 function but takes another prefix to be used. .TP \fwriteHrl(WsdlURL, HrlFilename)\fR Takes an URL pointing to an WSDL file. Will produce a file containing erlang records that corresponds to the elements and datatypes in the WSDL file. This '.hrl' file can then be included in your own Erlang code, for easy manipulation of the SOAP data. .TP \fwriteHrl(WsdlURL, HrlFilename, Prefix)\fR Works as the writeHrl/2 function but takes another prefix to be used. .SH AUTHOR Written by Torbjorn Tornkvist .SH "SEE ALSO" .BR yaws.conf (5) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/man/yaws.1�������������������������������������������������������������������������������0000664�0001750�0001750�00000017534�12605311412�011246� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH YAWS "1" "" "" "User Commands" -*- nroff -*- .SH NAME yaws \- yet another webserver .SH SYNOPSIS .B yaws [\fIOPTIONS\fR] .SH DESCRIPTION .\" Add any additional description here .PP Yaws is fast lightweight webserver. It can run as daemon or in interactive mode where it is possible to directly interact with the webserver. Yaws is particularly good at generating dynamic content. See the user docs for more information on that topic. .SH DAEMON/SERVER options .TP \fB\-i | --interactive\fR Interactive mode. This will start yaws in interactive mode with an erlang prompt. All error_logger messages will be written to the tty as well in this mode. Use this when developing yaws code. .TP \fB\-w | --winteractive\fR Cygwin inteactive mode (werl) .TP \fB\-D | --daemon\fR Daemon mode. This will start yaws as a daemon. .TP \fB\--heart\fR This will cause the yaws system to be automatically restarted in case it should crash. This switch also requires the \fI--daemon\fR switch to be present. .TP \fB\--heart-restart=C,T\fR This controls the number of restarts in a given time period that heart tolerates before refusing to restart Yaws. By default, heart allows up to 5 restarts within a 60 second period before refusing to restart Yaws again. This option allows up to \fIC\fR restarts in \fIT\fR seconds instead. To allow infinite restarts, set both \fIC\fR and \fIT\fR to 0. This switch automatically enables the \fI--heart\fR switch. .TP \fB\--debug\fR Debug mode. This will produce some auxiliary error output for some error conditions. It will also start the otp sasl lib for additional error printouts. .TP \fB\--nodebug\fR Non-debug mode. This is useful for running interactively via the \FI-i\fR option but without incurring the performance penalties of debug mode. .TP \fB\--conf file\fR Use a different configuration file than the default. If the configuration parameter \fIconfig\fR is set, yaws use it as default configuration file. Else, The default configuration file when running as root is /etc/yaws/yaws.conf. When running as a non priviliged user, yaws will search for its configuration file in the following order. First in $HOME/yaws.conf, then in ./yaws.conf and finally in /etc/yaws/yaws.conf. .TP \fB\--runmod module\fR Tells yaws to call \fImodule:start/0\fR at startup. This makes it possible to startup user specific applications together with yaws. .TP \fB\--pa path\fR Add path to the yaws system search path .TP \fB\--tracetraf\fR Traffic trace mode. All traffic will be written to a trace file called trace.traffic in the log directory. .TP \fB\--tracehttp\fR HTTP trace mode. All HTTP messages will be written to a trace file called trace.http in the log directory. .TP \fB\--traceout\fR When yaws is put into trace mode using either --tracetraf or --tracehttp, traces are written to files. If we provide the --traceout flag, the trace will also be written to stdout. .TP \fB\--trace\fR Sames as --tracetraf --traceout. I.e. trace everything and write to stdout. .TP \fB\--mnesiadir dir\fR Start Mnesia in directory <dir> .TP \fB\--sname xxx\fR Start yaws as a distributed erlang node with name <xxx> using the unqualified hostname as nodename postfix .TP \fB\--disable-kpoll\fR By default, yaws starts erlang with \fI+K true\fR. This flag reverses that. .TP \fB\--name xxx\fR Start yaws as a distributed erlang node with name <xxx> using the fully qualified hostname as nodename postfix .TP \fB\--proto_dist Mod\fR Use module Mod for erlang distribution. This is typically only used when we want to run erlang distribution over SSL. .TP \fB\--erlarg STRING\fR Pass STRING as an additional argument to the "erl" program. If STRING comprises multiple words, you must quote it so that your shell passes it to yaws as a single argument. If STRING contains any single quote characters, you must quote each of them as well. For example, to pass the option \fI-env NAME O'Keeffe\fR to "erl" from a Bourne-compatible shell: .PP .nf .ce --erlarg "-env NAME O\\'Keeffe" .fi .TP \fB\--id ID\fR This flag sets the id. If we're starting a daemon (or an interactive system) it gives the Yaws server the identity ID. This means that the server will write all internal files into the directory $HOME/.yaws/yaws/ID. Yaws also creates a file called $HOME/.yaws/yaws/ID/CTL which contains the portnumber the daemon is listening on for control request by the control command such as "yaws --hup" etc. If we're invoking a control command which should perform some control function on the daemon, we may have to give the --id flag also to the control command. If we don't do this the control command may interact with the wrong daemon due to finding the wrong "ctl" file. The daemon may also optionally specify the "id" in the yaws.conf configuration file. .TP \fB\--umask MASK\fR Set the umask for the daemon to MASK. .SH CONTROL OPTIONS .PP The following list of options are are used to control the daemon from the "outside" while it is running. .TP \fB\--hup [--id ID]\fR HUP the daemon. This forces the daemon to reread the configuration file. It also makes the daemon empty all its internal content caches. Hence when updating the doc root, HUPing the daemon is the fastest way to see the content updates. .TP \fB\--stop [--id id]\fR Stop the daemon (called id) .TP \fB\--ls \fR Lists current ids and status of all yaws servers on localhost. In practice this amounts to a listdir in $HOME/.yaws/yaws - and check whether the different systems who has created files there are alive. .TP \fB--status [--id id]\fR Query a running yaws daemon for its status, and print it. .TP \fB--stats [--id id]\fR Query a running yaws daemon for its statistics, and print it. .TP \fB--running-config [--id id]\fR Query a running yaws daemon for its current configuration, and print it. This can be useful when attempting to figure out how to set config in embedded mode. Configure yaws to you liking in non-embedded mode, run this command and use the output to populate the embedded mode records. .TP \fB--load Modules [--id id]\fR Try to (re)load erlang modules into a running daemon. This is useful after modifying appmods or modules used by scripts. .TP \fB--debug-dump [--id id]\fR Produce a debug dump on stdout. In particular this code lists what we refer to as suspicious processes. I.e. processes that might be hanging or processes that are "large" - hardcoded to 40k words. .TP \fB--ctltrace [--id ID] http | traffic | off\fR Control the trace capabilities of a running yaws daemon. If the http or traffic option is given, the daemon will write a log for debug purposes into the logdir. .TP \fB--wait-started[=T] [--id ID] \fR Waits at most 30 seconds for the server to start. Exits with 0 if server is running, 1 otherwise. Typically useful in test scripts. The default 30 seconds can be modified by appending \fI=T\fR to the option, where \fIT\fR is the desired number of seconds to wait for the server to start. .SH MISC OPTIONS .TP \fB--check YawsFile [IncDirs ....]\fR Test compile a `.yaws' file. Useful in Makefiles when we want to ensure that all .yaws files are syntactically correct .TP \fB\--version\fR output version information and exit .SH ENVIRONMENT VARIABLES .TP \fBHOME\fR Is used to determine where we write the temporary files. By default all tmp files end up in $HOME/.yaws. This includes the JIT files that are the result of processed .yaws files and also the so called control file that is used by the daemon to write the port number to which it is listening for control commands such as "yaws --status" Thus HOME is the handle we use in the control commands to find the control file so that we know where to connect to. .TP \fBYAWSHOME\fR Can be used to override the HOME variable. This is useful when we for example are running yaws under port binding programs such as authpriv. It's useful by distros that don't want Yaws to write any files ever in the HOME directory of root. .SH AUTHOR Written by Claes Wikstrom .SH "SEE ALSO" .BR yaws.conf (5) .BR erl (1) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/man/yaws.conf.5��������������������������������������������������������������������������0000664�0001750�0001750�00000151353�12605311412�012174� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH YAWS.CONF "5" "" "" "User Commands" -*- nroff -*- .SH NAME /etc/yaws/yaws.conf \- Configuration file for the Yaws web server .SH DESCRIPTION .\" Add any additional description here .PP Yaws is fast lightweight web server. It reads a configuration file called yaws.conf to control its operations. The configuration contains two distinct parts: a global part which affects all the virtual hosts and a server part where options for each virtual host is supplied. .SH GLOBAL PART .TP \fBlogdir = [+]Directory\fR All Yaws logs will be written to files in this directory. If specified with \fB+\fR, Yaws will attempt to create the directory if it does not exist. There are several different log files written by Yaws: \fBreport.log\fR - this is a text file that contains all error logger printouts from Yaws. \fB<Host>.access\fR - for each virtual host served by Yaws, a file <Host>.access will be written that contains an access log in NCSA combined/XLF/ELF log format. (See http://www.w3.org/TR/WD-logfile.html for more details on Extended Log File Format.) \fB<Host>.auth\fR - for each virtual host served by Yaws, a file <Host>.auth will be written which contains all http auth related messages. \fBtrace_<YYYYMMDD_hhmmss>\fR - Trace files are written in this subdirectory, suffixed by the creation date. .RS 12 \fBtrace.<Pid>.http\fR - this file contains the HTTP trace if that is enabled, where <Pid> is the process id handling the TCP connection. \fBtrace.<Pid>.traffic\fR - this file contains the traffic trace if that is enabled, where <Pid> is the process id handling the TCP connection. .RE .IP Note that <Host>.access and <Host>.auth files will be used only if the directive \fBlogger_mod\fR is not set or set to yaws_log. The default value for logdir is \fI"."\fR .TP \fBebin_dir = Directory\fR This directive adds Directory to the Erlang search path. It is possible to have several of these commands in the configuration file. The default value is \fI"yaws_dir"/examples/ebin\fR .TP \fBsrc_dir = Directory\fR This directive defines a Directory as a \fIsource\fR directory. Yaws will compile all erlang modules found in this directory and all its subdirectories. The compilation occurs when the configuration is loaded or reloaded. The \fBinclude_dir\fR directives are used to search for includes files. Multiple \fBsrc_dir\fR directives may be used. There is no such directory configured by default. .TP \fBid = String\fR It is possible to run multiple Yaws servers on the same machine. We use the id of a Yaws server to control it using the different control commands such as: .nf # /usr/local/bin/yaws --id foobar --stop .fi To stop the Yaws server with id "foobar". Each Yaws server will write its internal data into a file called $HOME/.yaws/yaws/ID where ID is the identity of the server. Yaws also creates a file called $HOME/.yaws/yaws/ID/CTL which contains the port number where the server is listening for control commands. The default id is \fI"default"\fR. .TP \fBserver_signature = String\fR This directive sets the "Server: " output header to the custom value. The default value is \fI"yaws/%VSN%, Yet Another Web Server"\fR. .TP \fBinclude_dir = Directory\fR This directive adds Directory to the path of directories where the Erlang compiler searches for include files. We need to use this if we want to include .hrl files in our Yaws Erlang code. It is possible to have several of these commands in the configuration file. The default value is \fI"yaws_dir"/examples/include\fR. .TP \fBmax_num_cached_files = Integer\fR Yaws will cache small files such as commonly accessed GIF images in RAM. This directive sets a maximum number on the number of cached files. The default value is \fI400\fR. .TP \fBmax_num_cached_bytes = Integer\fR This directive controls the total amount of RAM which can maximally be used for cached RAM files. The default value is \fI1000000\fR, 1 megabyte. .TP \fBmax_size_cached_file = Integer\fR This directive sets a maximum size on the files that are RAM cached by Yaws. The default value is \fI8000\fR, 8 kBytes. .TP \fBcache_refresh_secs = Integer\fR The RAM cache is used to serve pages that sit in the cache. An entry sits in cache at most cache_refresh_secs number of seconds. The default is \fI30\fR. This means that when the content is updated under the docroot, that change doesn't show until 30 seconds have passed. While developing a Yaws site, it may be convenient to set this value to 0. If the debug flag (-d) is passed to the Yaws start script, this value is automatically set to 0. .TP \fBtrace = false | traffic | http\fR This enables traffic or http tracing. Tracing is also possible to enable with a command line flag to Yaws. Default is \fIfalse\fR. .TP \fBuse_old_ssl = true | false\fR This re-enables the old OTP SSL implementation. By default we use the new SSL implementation. .TP \fBauth_log = true | false\fR \fBDeprecated and ignored. Now, this target must be set in server part.\fR .TP \fBmax_connections = nolimit | Integer\fR Set this value to control the maximum number of connections from HTTP clients into the server. This is implemented by closing the last socket if the limit threshold is reached. .TP \fBkeepalive_maxuses = nolimit | Integer\fR Normally, Yaws does not restrict the number of times a connection is kept alive using keepalive. Setting this parameter to an integer X will ensure that connections are closed once they have been used X times. This can be a useful to guard against long running connections collecting too much garbage in the Erlang VM. .TP \fBprocess_options = undefined | Proplist\fR Set process spawn options for client acceptor processes. Options must be specified as a quoted string of either the atom \fIundefined\fR or as a proplist of valid process options. The supported options are \fIfullsweep_after\fR, \fImin_heap_size\fR, and \fImin_bin_vheap_size\fR, each taking an associated integer value. Other process options are ignored. The proplist may also be empty. See \fBerlang:spawn_opt/4\fR for details on these options. .TP \fBlarge_file_chunk_size = Integer\fR Set the chunk size used by Yaws to send large files when sendfile is not supported or disabled. The default value is \fI10240\fR. .TP \fBlarge_file_sendfile = erlang | yaws | disable\fR Set the version of sendfile method to use to send large files (if supported): \fBerlang\fR - use \fIfile:sendfile/5\fR, if supported. \fByaws\fR - use Yaws sendfile linked-in driver, if supported. \fBdisable\fR - do not use any sendfile method, but \fIgen_tcp:send/2\fR. The default value is \fIyaws\fR. .TP \fBacceptor_pool_size = Integer\fR Set the size of the pool of cached acceptor processes. The specified value must be greater than or equal to 0. The default value is \fI8\fR. Specifying a value of 0 effectively disables the process pool. .TP \fBlog_wrap_size = Integer\fR The logs written by Yaws are all wrap logs, the default value at the size where they wrap around and the original gets renamed to File.old is \fI1000000\fR, 1 megabyte. This value can be changed. .br If we set the value to 0 the logs will never wrap. If we want to use Yaws in combination with a more traditional log wrapper such as logrotate, set the size to 0 and Yaws will reopen the logfiles once they have be renamed/removed. .TP \fBlog_resolve_hostname = true | false\fR By default the client host IP is not resolved in the access logs. .TP \fBfail_on_bind_err = true | false\fR Fail completely or not if Yaws fails to bind a listen socket Default is \fItrue\fR. .TP \fBenable_soap = true | false\fR If true, a soap server will be started at startup of Yaws. Default is \fIfalse\fR. .TP \fBsoap_srv_mods = ListOfModuleSetting\fR If enable_soap is true, a startup Yaws will invoke \fIyaws_soap_srv:setup()\fR to setup modules set here. ModuleSetting is either a triad like \fI<Mod, HandlerFunc, WsdlFile>\fR or a quadruple form like \fI<Mod, HandlerFunc, WsdlFile, Prefix>\fR which specifies the \fIprefix\fR. A \fIprefix\fR will be used as argument of \fIyaws_soap_lib:initModel()\fR and then be used as a XML namespace prefix. Note, the \fIWsdlFile\fR here should be an absolute-path file in local file systems. For example, we can specify .nf soap_srv_mods=<Mod1, Handler, Wsdl1> <Mod2, Handler, Wsdl2, Prefix> ... .fi .TP \fBphp_exe_path = Path\fR \fBthis target is deprecated and useless. use 'php_handler' target in server part instead.\fR .br The name of (and possibly path to) the php executable used to interpret php scripts (if allowed). Default is \fIphp_exe_path = php-cgi\fR. .TP \fBcopy_error_log = true | false\fR Enable or disable copying of the error log. When we run in embedded mode, there may very well be some other systems process that is responsible for writing the errorlog to a file whereas when we run in normal standalone mode, we typically want the Erlang errorlog written to a report.log file. Default value is \fItrue\fR. .TP \fBysession_mod = Module\fR Allows to specify a different Yaws session storage mechanism instead of an ETS table. One of the drawbacks of the default yaws_session_server implementation is that server side cookies are lost when the server restarts. Specifying a different module here will pass all write/read operations to this module (it must implement appropriate callbacks). .TP \fBrunmod = ModuleName\fR At startup Yaws will invoke \fIModuleName:start()\fR in a separate process. It is possible to have several runmods. This is useful if we want to reuse the Yaws startup shell script for our own application. .TP \fBpick_first_virthost_on_nomatch = true | false\fR When Yaws gets a request, it extracts the Host header from the client request to choose a virtual server amongst all servers with the same IP/Port pair. This configuration parameter decides whether Yaws should pick the first server (as defined in the yaws.conf file) if no name match or not. If this is false and no Host header is present in the request, Yaws returns a 400 Bad Request as required by the HTTP standard. In real live hosting scenarios we typically want this to be false, whereas in testing/development scenarios it may be convenient to set it to true. Default is \fItrue\fR. .TP \fBkeepalive_timeout = TimeInMilliseconds | infinity\fR If the HTTP session will be kept alive (i.e., not immediately closed) it will close after keepalive_timeout milliseconds unless a new request is received in that time. The default value is \fI30000\fR. The value \fIinfinity\fR is legal but not recommended. .TP \fBsubconfig = File\fR Load specified config file. Absolute paths or relative ones to the configuration location are allowed. Unix-style wildcard strings can be used to include several files at once. See \fIfilelib:wildcard/1\fR for details. Hidden files, starting by a dot, will be ignored. For example: .nf subconfig = /etc/yaws/global.conf subconfig = /etc/yaws/vhosts/*.conf .fi Or, relatively to the configuration location: .nf subconfig = global.conf subconfig = vhosts/*.conf .fi \fBWARNING: because of a bug in filelib:wildcard/2, wildcard strings are forbidden for Erlang/OTP R15B03 and previous.\fR .TP \fBsubconfigdir = Directory\fR Load all config files found in the specified directory. The given Directory can be an absolute path or relative to the configuration location. Hidden files, starting by a dot, will be ignored. .TP \fBx_forwarded_for_log_proxy_whitelist = ListOfUpstreamProxyServerIps\fR \fBthis target is deprecated and will be ignored.\fR .TP \fBdefault_type = MimeType\fR Defines the default MIME type to be used where Yaws cannot determine it by its MIME types mappings. Default is \fItext/plain\fR. .TP \fBdefault_charset = Charset\fR Defines the default charset to be added when a response content-type is \fItext/*\fR. By default, no charset is added. .TP \fBmime_types_file = File\fR Overrides the default \fImime.types\fR file included with Yaws. This file must use the following format: .nf # Lines beginning with a '#' or a whitespace are ignored # blank lines are also ignored <MIME type> <space separated file extensions> .fi The default file is located at \fI${PREFIX}/lib/yaws/priv/mime.types\fR. You should not edit this file because it may be replaced when you upgrade your server. .TP \fBadd_types = ListOfTypes\fR Specifies one or more mappings between MIME types and file extensions. More than one extension can be assigned to a MIME type. \fIListOfTypes\fR is defined as follows: .nf add_types = <MimeType1, Ext> <MimeType2, Ext1 Ext2 ...> ... .fi The mappings defined using this directive will overload all other definitions. If a file extension is defined several times, only the last one is kept. Multiple \fBadd_types\fR directives may be used. .TP \fBadd_charsets = ListOfCharsets\fR Specifies one or more mappings between charsets and file extensions. More than one extension can be assigned to a charset. \fIListOfCharsets\fR is defined as follows: .nf add_charsets = <Charset1, Ext> <Charset2, Ext1 Ext2 ...> ... .fi The mappings defined using this directive will overload all other definitions. If a file extension is defined several times, only the last one is kept. Multiple \fBadd_charsets\fR directives may be used. .SH SERVER PART Yaws can virthost several web servers on the same IP address as well as several web servers on different IP addresses. This includes SSL servers. .PP Each virtual host is defined within a matching pair of \fB<server ServerName>\fR and \fB</server>\fR. The ServerName will be the name of the webserver. .PP The following directives are allowed inside a server definition. .TP \fBport = Port\fR This makes the server listen on Port. Default is \fI8000\fR. .TP \fBlisten = IpAddress\fR This makes the server listen on IpAddress. When virthosting several servers on the same ip/port address, if the browser doesn't send a Host: field, Yaws will pick the \fIfirst\fR server specified in the config file. If the specified IP address is 0.0.0.0 Yaws will listen on all local IP addresses on the specified port. Default is \fI127.0.0.1\fR. Multiple \fBlisten\fR directives may be used to specify several addresses to listen on. .TP \fBlisten_backlog = Integer\fR This sets the TCP listen backlog for the server to define the maximum length the queue of pending connections may grow to. The default is 1024. .TP \fB<listen_opts> ... </listen_opts>\fR Defines extra options to be set on the listen socket and, by inheritance, on accepted sockets. See \fIinet:setopts/2\fR for details. Supported options are: \fBbuffer = Integer\fR (default: same as \fIinet:setopts/2\fR) \fBdelay_send = true | false \fR (default: same as \fIinet:setopts/2\fR) \fBlinger = Integer | false \fR (default: same as \fIinet:setopts/2\fR) \fBnodelay = true | false \fR (default: same as \fIinet:setopts/2\fR) \fBpriority = Integer\fR (default: same as \fIinet:setopts/2\fR) \fBsndbuf = Integer\fR (default: same as \fIinet:setopts/2\fR) \fBrecbuf = Integer\fR (default: same as \fIinet:setopts/2\fR) \fBsend_timeout = Integer | infinity\fR (default: same as \fIinet:setopts/2\fR) \fBsend_timeout_close = true | false \fR (default: same as \fIinet:setopts/2\fR) .RE .TP \fBserver_signature = String\fR This directive sets the "Server: " output header to the custom value and overloads the global one for this virtual server. .TP \fBsubconfig = File\fR Same as \fBsubconfig\fR directive of the global part, but here files should only contain directives allowed in the server part. .TP \fBsubconfigdir = Directory\fR Same as \fBsubconfigdir\fR directive of the global part, but here files should only contain directives allowed in server part. .TP \fBrhost = Host[:Port]\fR This forces all local redirects issued by the server to go to Host. This is useful when Yaws listens to a port which is different from the port that the user connects to. For example, running Yaws as a non-privileged user makes it impossible to listen to port 80, since that port can only be opened by a privileged user. Instead Yaws listens to a high port number port, 8000, and iptables are used to redirect traffic to port 80 to port 8000 (most NAT:ing firewalls will also do this for you). .TP \fBrmethod = http | https\fR This forces all local redirects issued by the server to use this method. This is useful when an SSL off-loader, or stunnel, is used in front of Yaws. .TP \fBauth_log = true | false\fR Enable or disable the auth log for this virtual server. Default is \fItrue\fR. .TP \fBaccess_log = true | false\fR Setting this directive to false turns off traffic logging for this virtual server. The default value is \fItrue\fR. .TP \fBlogger_mod = Module\fR It is possible to set a special module that handles access and auth logging. The default is to log all web server traffic to <Host>.access and <Host>.auth files in the configured or default logdir. .br This module must implement the behaviour \fIyaws_logger\fR. Default value is \fIyaws_log\fR. The following functions should be exported: \fBModule:open_log(ServerName, Type, LogDir)\fR .RS 12 When Yaws is started, this function is called for this virtual server. If the initialization is successful, the function must return \fI{true,State}\fR and if an error occurred, it must return \fIfalse\fR. .RE .IP \fBModule:close_log(ServerName, Type, State)\fR .RS 12 This function is called for this virtual server when Yaws is stopped. .RE .IP \fBModule:wrap_log(ServerName, Type, State, LogWrapSize)\fR .RS 12 This function is used to rotate log files. It is regularly called by Yaws and must return the possibly updated internal NewState. .RE .IP \fBModule:write_log(ServerName, Type, State, Infos)\fR .RS 12 When it needs to log a message, Yaws will call this function. The parameter Infos is \fI{Ip,Req,InHdrs,OutHdrs,Time}\fR for an access log and \fI{Ip,Path,Item}\fR for an auth log, where: \fBIp\fR - IP address of the accessing client (as a tuple). \fBReq\fR - the HTTP method, URI path, and HTTP version of the request (as a #http_request{} record). \fBInHdrs\fR - the HTTP headers which were received from the WWW client (as a #headers{} record). \fBOutHdrs\fR - the HTTP headers sent to the WWW client (as a #outh{} record) \fBPath\fR - the URI path of the request (as a string). \fBItem\fR - the result of an authentication request. May be \fI{ok,User}\fR, \fI403\fR or \fI{401,Realm}\fR. \fBTime\fR - The time taken to serve the request, in microseconds. .RE .IP For all of these callbacks, \fBServerName\fR is the virtual server's name, \fIType\fR is the atom access or auth and \fIState\fR is the internal state of the logger. .TP \fBshaper = Module\fR Defines a module to control access to this virtual server. Access can be controlled based on the IP address of the client. It is also possible to throttle HTTP requests based on the client's download rate. This module must implement the behaviour \fIyaws_shaper\fR. There is no such module configured by default. .TP \fBdir_listings = true | true_nozip | false\fR Setting this directive to false disallows the automatic dir listing feature of Yaws. A status code 403 Forbidden will be sent. Set to true_nozip to avoid the auto-generated all.zip entries. Default is \fIfalse\fR. .TP \fBextra_cgi_vars = .....\fR Add additional CGI or FastCGI variables. For example: .nf <extra_cgi_vars dir='/path/to/some/scripts'> var = val \&... </extra_cgi_vars> .fi .TP \fBstatistics = true | false\fR Turns on/off statistics gathering for a virtual server. Default is \fIfalse\fR. .TP \fBfcgi_app_server = Host:Port\fR The hostname and TCP port number of a FastCGI application server. To specify an IPv6 address, put it inside square brackets (ex: "[::1]:9000"). The TCP port number is not optional. There is no default value. .TP \fBfcgi_trace_protocol = true | false\fR Enable or disable tracing of FastCGI protocol messages as info log messages. Disabled by default. .TP \fBfcgi_log_app_error = true | false\fR Enable or disable logging of application error messages (output to stderr and non-zero exit value). Disabled by default. .TP \fBdeflate = true | false\fR Turns on or off deflate compression for a server. Default is \fIfalse\fR. .TP \fB<deflate> ... </deflate>\fR This begins and ends the deflate compression configuration for this server. The following items are allowed within a matching pair of <deflate> and </deflate> delimiters. \fBmin_compress_size = nolimit | Integer\fR .RS 12 Defines the smallest response size that will be compressed. If nolimit is not used, the specified value must be strictly positive. The default value is \fInolimit\fR. .RE .IP \fBcompress_level = none | default | best_compression | best_speed | 0..9\fR .RS 12 Defines the compression level to be used. 0 (none), gives no compression at all, 1 (best_speed) gives best speed and 9 (best_compression) gives best compression. The default value is \fIdefault\fR. .RE .IP \fBwindow_size = 9..15\fR .RS 12 Specifies the zlib compression window size. It should be in the range 9 through 15. Larger values of this parameter result in better compression at the expense of memory usage. The default value is \fI15\fR. .RE .IP \fBmem_level = 1..9\fR .RS 12 Specifies how much memory should be allocated for the internal compression state. \fImem_level=1\fR uses minimum memory but is slow and reduces compression ratio; \fImem_level=9\fR uses maximum memory for optimal speed. The default value is \fI8\fR. .RE .IP \fBstrategy = default | filtered | huffman_only\fR .RS 12 This parameter is used to tune the compression algorithm. See \fBzlib(3erl)\fR for more details on the \fIstrategy\fR parameter. The default value is \fIdefault\fR. .RE .IP \fBuse_gzip_static = true | false\fR .RS 12 If true, Yaws will try to serve precompressed versions of static files. It will look for precompressed files in the same location as original files that end in ".gz". Only files that do not fit in the cache are concerned. The default value is \fIfalse\fR. .RE .IP \fBmime_types = ListOfTypes | defaults | all\fR .RS 12 Restricts the deflate compression to particular MIME types. The special value \fIall\fR enable it for all types (It is a synonym of `*/*'). MIME types into \fIListOfTypes\fR must have the form `type/subtype' or `type/*' (indicating all subtypes of that type). Here is an example: .nf mime_types = default image/* mime_types = application/xml application/xhtml+xml application/rss+xml .fi By default, the following MIME types are compressed (if \fBdeflate\fR is set to true): \fItext/*, application/rtf, application/msword, application/pdf, application/x-dvi, application/javascript, application/x-javascript\fR. Multiple \fBmime_types\fR directive can be used. .RE .TP \fBdocroot = Directory ...\fR This makes the server serve all its content from Directory. .br It is possible to pass a space-separated list of directories as docroot. If this is the case, the various directories will be searched in order for the requested file. This also works with the ssi and yssi constructs where the full list of directories will be searched for files to ssi/yssi include. Multiple docroot directives can be used. You need at least one valid docroot, invalid docroots are skipped with their associated auth structures. .TP \fBauth_skip_docroot = true | false\fR If true, the docroot will not be searched for \fI.yaws_auth\fR files. This is useful when the docroot is quite large and the time to search it is prohibitive when Yaws starts up. Defaults to \fIfalse\fR. .TP \fBpartial_post_size = Integer | nolimit\fR When a Yaws file receives large POSTs, the amount of data received in each chunk is determined by this parameter. The default value is \fI10240\fR. Setting it to nolimit is potentially dangerous. .TP \fBdav = true | false\fR Turns on the DAV protocol for this server. The dav support in Yaws is highly limited. If dav is turned on, .yaws processing of .yaws pages is turned off. Default is \fIfalse\fR. The socket read timeout is supplied by the keepalive_timeout setting. If the read is not done within the timeout, the POST will fail. .TP \fBtilde_expand = true|false\fR If this value is set to false Yaws will never do tilde expansion. The default is \fIfalse\fR. tilde_expansion is the mechanism whereby a URL on the form http://www.foo.com/~username is changed into a request where the docroot for that particular request is set to the directory ~username/public_html/. .TP \fBallowed_scripts = ListOfSuffixes\fR The allowed script types for this server. Recognized are `yaws', `cgi', `fcgi', `php'. Default is \fIallowed_scripts = yaws php cgi fcgi\fR. Note: for fcgi scripts, the FastCGI application server is only called if a local file with the .fcgi extension exists. However, the contents of the local .fcgi file are ignored. .TP \fBtilde_allowed_scripts = ListOfSuffixes\fR The allowed script types for this server when executing files in a users public_html folder Recognized are `yaws', `cgi', `fcgi', `php'. Default is \fItilde_allowed_scripts =\fR i.e. empty .TP \fBindex_files = ListOfResources\fR This directive sets the list of resources to look for, when a directory is requested by the client. If the last entry begins with a `/', and none of the earlier resources are found, Yaws will perform a redirect to this uri. Default is \fIindex_files = index.yaws index.html index.php\fR. .TP \fBappmods = ListOfModuleNames\fR If any of the names in ListOfModuleNames appear as components in the path for a request, the path request parsing will terminate and that module will be called. There is also an alternate syntax for specifying the appmods if we don't want our internal erlang module names to be exposed in the URL paths. We can specify .nf appmods = <Path1, Module1> <Path2, Modules2> ... .fi Assume for example that we have the URL http://www.hyber.org/myapp/foo/bar/baz?user=joe while we have the module foo defined as an appmod, the function foo:out(Arg) will be invoked instead of searching the filesystems below the point foo. .br The Arg argument will have the missing path part supplied in its appmoddata field. It is also possible to exclude certain directories from appmod processing. This is particulaly interesting for '/' appmods. Here is an example: .nf appmods = </, myapp exclude_paths icons js top/static> .fi The above configuration will invoke the 'myapp' erlang module on everything except any file found in directories 'icons', 'js' and 'top/static' relative to the docroot. .TP \fBdispatchmod = DispatchModule\fR Set \fIDispatchModule\fR as a server-specific request dispatching module. Yaws expects \fIDispatchModule\fR to export a \fIdispatch/1\fR function. When it receives a request, Yaws passes an \fI#arg{}\fR record to the dispatch module's \fIdispatch/1\fR function, which returns one of the following atom results: .RS 12 \fBdone\fR - this indicates the dispatch module handled the request itself and already sent the response, and Yaws should resume watching for new requests on the connection \fBclosed\fR - same as \fIdone\fR but the \fIDispatchModule\fR also closed the connection \fBcontinue\fR - the dispatch module has decided not to handle the request, and instead wants Yaws to perform its regular request dispatching .RE .IP Note that when \fIDispatchModule\fR handles a request itself, Yaws does not support tracing, increment statistics counters or allow traffic shaping for that request. It does however still keep track of maximum keepalive uses on the connection. .TP \fBerrormod_404 = Module\fR It is possible to set a special module that handles 404 Not Found messages. The function \fIModule:out404(Arg, GC, SC)\fR will be invoked. The arguments are .RS 12 \fBArg\fR - a #arg{} record \fBGC\fR - a #gconf{} record (defined in yaws.hrl) \fBSC\fR - a #sconf{} record (defined in yaws.hrl) .RE .IP The function can and must do the same things that a normal \fIout/1\fR does. .TP \fBerrormod_401 = Module\fR It is possible to set a special module that handles 401 Unauthorized messages. This can for example be used to display a login page instead. The function \fIModule:out401(Arg, Auth, Realm)\fR will be invoked. The arguments are .RS 12 \fBArg\fR - a #arg{} record \fBAuth\fR - a #auth{} record \fBRealm\fR - a string .RE .IP The function can and must do the same things that a normal \fIout/1\fR does. .TP \fBerrormod_crash = Module\fR It is possible to set a special module that handles the HTML generation of server crash messages. The default is to display the entire formatted crash message in the browser. This is good for debugging but not in production. .br The function \fIModule:crashmsg(Arg, SC, Str)\fR will be called. The \fIStr\fR is the real crash message formatted as a string. .br The function must return, \fI{content,MimeType,Cont}\fR or \fI{html, Str}\fR or \fI{ehtml, Term}\fR. That data will be shipped to the client. .TP \fBexpires = ListOfExpires\fR Controls the setting of the \fIExpires\fR HTTP header and the \fImax-age\fR directive of the \fICache-Control\fR HTTP header in server responses for specific MIME types. The expiration date can be set as relative to either the time the source file was last modified; as the time of the client access; or as always in order to empty the cache altogether. ListOfExpires is defined as follows: .nf expires = <MimeType1, access+Seconds> <MimeType2, modify+Seconds> <MimeType3, always> ... .fi A MimeType can also have a wildcard as subtype or both as subtype and type, like type/* or */*. These HTTP headers are an instruction to the client about the document's validity and persistence. If cached, the document may be fetched from the cache rather than from the source until this time has passed. After that, the cache copy is considered "expired" and invalid, and a new copy must be obtained from the source. Here is an example: .nf expires = <image/gif, access+2592000> <image/png, access+2592000> expires = <image/jpeg, access+2592000> <text/css, access+2592000> expires = <text/*, always> .fi and here is another: .nf expires = <*/*, always> .fi .TP \fBarg_rewrite_mod = Module\fR It is possible to install a module that rewrites all the Arg #arg{} records at an early stage in the Yaws server. This can be used to do various things such as checking a cookie, rewriting paths etc. An arg_rewrite_mod must export an \fIarg_rewrite/1\fR function taking and returning an #arg{} record. If the function wants to return a response, it must set the #arg.state field of its return value to an instance of the #rewrite_response{} record. The module \fIyaws_vdir\fR can be used in case you want to serve static content that is not located in your docroot. See the example at the bottom of this man page for how to use the \fIopaque\fR + \fIvdir\fR elements to instruct the \fIyaws_vdir\fR module what paths to rewrite. .TP \fBstart_mod = Module\fR Defines a user provided callback module. At startup of the server, Module:start/1 will be called. The #sconf{} record (defined in yaws.hrl) will be used as the input argument. This makes it possible for a user application to synchronize the startup with the Yaws server as well as getting hold of user specific configuration data, see the explanation for the <opaque> context. .TP \fBrevproxy = Prefix Url [intercept_mod Module]\fR Make Yaws a reverse proxy. \fIPrefix\fR is a path inside our own docroot and \fIUrl\fB argument is a URL pointing to a website we want to "mount" under the \fIPrefix\fR path. This example: .nf revproxy = /tmp/foo http://yaws.hyber.org .fi makes the hyber website appear under \fI/tmp/foo\fR. It is possible to have multiple reverse proxies inside the same server. You can optionally configure an interception module for each reverse proxy, allowing your application to examine and modify requests and HTTP headers as they pass through the proxy from client to backend server and also examine and modify responses and HTTP headers as they return from the backend server through the proxy to the client. You specify an interception module by including the optional \fIintercept_mod\fR keyword followed by \fIModule\fR, which should be the name of your interception module. An interception module is expected to export two functions: \fIrewrite_request/2\fR and \fIrewrite_response/2\fR. The two arguments passed to \fIrewrite_request/2\fR function are a \fI#http_request{}\fR record and a \fI#headers{}\fR record, whereas \fIrewrite_response/2\fR function takes a \fI#http_response{}\fR record and also a \fI#headers{}\fR record. You can find definitions for these record types in the \fIyaws_api.hrl\fR header file. Each function can examine each record instance and can either return each original instance or can return a modified copy of each instance in its response. The \fIrewrite_request/2\fR function should return a tuple of the following form: .nf \fI{ok, #http_request{}, #headers{}}\fR .fi and the \fIrewrite_response/2\fR function should similarly return a tuple of the following form: .nf \fI{ok, #http_response{}, #headers{}}\fR .fi A \fI#headers{}\fR record can easily be manipulated in an interceptor using the functions listed below: .nf \fIyaws_api:set_header/2\fR, \fIyaws_api:set_header/3\fR \fIyaws_api:get_header/2\fR, \fIyaws_api:get_header/3\fR \fIyaws_api:delete_header/2\fR .fi Any failures in your interception module's functions will result in HTTP status code 500, indicating an internal server error. .TP \fBfwdproxy = true|false\fR Make Yaws a forward proxy. By enabling this option you can use Yaws as a proxy for outgoing web traffic, typically by configuring the proxy settings in a web-browser to explicitly target Yaws as its proxy server. .TP \fBservername = Name\fR If we're virthosting several servers and want to force a server to match specific Host: headers we can do this with the "servername" directive. This name doesn't necessarily have to be the same as the the name inside <server Name> in certain NAT scenarios. Rarely used feature. .TP \fBserveralias = ListOfNames\fR This directive sets the alternate names for a virtual host. A server alias may contain wildcards: .RS 12 '*' matches any sequence of zero or more characters '?' matches one character unless that character is a period ('.') .RE .IP Multiple \fBserveralias\fR directives may be used. Here is an example: .nf <server server.domain.com> serveralias = server server2.domain.com server2 serveralias = *.server.domain.com *.server?.domain.com ... </server> .fi .TP \fBphp_handler = <Type, Spec>\fR Set handler to interpret .php files. It can be one of the following definitions: \fBphp_handler = <cgi, Filename>\fR - The name of (and possibly path to) the php executable used to interpret php scripts (if allowed). \fBphp_handler = <fcgi, Host:Port>\fR - Use the specified fastcgi server to interpret .php files (if allowed). .RS 12 Yaws does not start the PHP interpreter in fastcgi mode for you. To run PHP in fastcgi mode, call it with the -b option. For example: .nf php5-cgi -b '127.0.0.1:54321' .fi This starts a php5 in fastcgi mode listening on the local network interface. To make use of this PHP server from Yaws, specify: .nf php_handler = <fcgi, 127.0.0.1:54321> .fi If you need to specify an IPv6 address, use square brackets: .nf php_handler = <fcgi, [::1]:54321> .fi The PHP interpreter needs read access to the files it is to serve. Thus, if you run it in a different security context than Yaws itself, make sure it has access to the .php files. .br Please note that anyone who is able to connect to the php fastcgi server directly can use it to read any file to which it has read access. You should consider this when setting up a system with several mutually untrusted instances of php. .RE .IP \fBphp_handler = <extern, Module:Function | Node:Module:Function>\fR - Use an external handler, possibly on another node, to interpret .php files (if allowed). .RS 12 To interpret a .php file, the function \fIModule:Function(Arg)\fR will be invoked (Evaluated inside a rpc call if a \fINode\fR is specified), where Arg is an #arg{} record. .br The function must do the same things that a normal out/1 does. .RE .IP Default value is \fI<cgi, "/usr/bin/php-cgi">\fR. .TP \fBphpfcgi = Host:Port\fR \fBthis target is deprecated. use 'php_handler' target in server part instead.\fR .br Using this directive is the same as: php_handler = <fcgi, Host:Port>. .TP \fBdefault_type = MimeType\fR Overloads the global \fBdefault_type\fR value for this virtual server. .TP \fBdefault_charset = Charset\fR Overloads the global \fBdefault_charset\fR value for this virtual server. .TP \fBmime_types_file = File\fR Overloads the global \fBmime_type_file\fR value for this virtual server. Mappings defined in \fIFile\fR will not overload those defined by \fBadd_types\fR directives in the global part. .TP \fBadd_types = ListOfTypes\fR Overloads the global \fBadd_types\fR values for this virtual server. If a mapping is defined in the global part and redefined in a server part using this directive, then it is replaced. Else it is kept. .TP \fBadd_charsets = ListOfCharsets\fR Overloads the global \fBadd_charsets\fR values for this virtual server. If a mapping is defined in the global part and redefined in a server part using this directive, then it is replaced. Else it is kept. .TP \fBnslookup_pref = [inet | inet6]\fR For fcgi servers and revproxy URLs, define the name resolution preference. For example, to perform only IPv4 name resolution, use [inet]. To do both IPv4 and IPv6 but try IPv6 first, use [inet6, inet]. Default value is [inet]. .TP \fB<ssl> ... </ssl>\fR This begins and ends an SSL configuration for this server. It's possible to virthost several SSL servers on the same IP given that they all share the same certificate configuration. In general it is complicated to virthost several SSL servers on the same IP address since the certificate is typically bound to a domainname in the common name part of the certificate. One solution (the only?) to this problem is to have a certificate with multiple subjectAltNames. See http://wiki.cacert.org/VhostTaskForce#Interoperability_Test \fBkeyfile = File\fR .RS 12 Specifies which file contains the private key for the certificate. If not specified then the certificate file will be used. .RE .IP \fBcertfile = File\fR .RS 12 Specifies which file contains the certificate for the server. .RE .IP \fBcacertfile = File\fR .RS 12 A file containing trusted certificates to use during client authentication and to use when attempting to build the server certificate chain. The list is also used in the list of acceptable client CAs passed to the client when a certificate is requested. .RE .IP \fBdhfile = File\fR .RS 12 A file containing PEM-encoded Diffie-Hellman parameters to be used by the server if a cipher suite using Diffie-Hellman key exchange is negotiated. If not specified, default parameters are used. .RE .IP \fBverify = 0 | 1 | 2 | verify_none | verify_peer\fR .RS 12 Specifies the level of verification the server does on client certs. 0 means that the server will not ask for a cert (verify_none), 1 means that the server will ask the client for a cert but not fail if the client does not supply a client cert (verify_peer, fail_if_no_peer_cert = false), 2 means that the server requires the client to supply a client cert (verify_peer, fail_if_no_peer_cert = true). Setting verify_none means that the x509 validation will be skipped (no certificate request is sent to the client), verify_peer means that a certificate request is sent to the client (x509 validation is performed. You might want to use fail_if_no_peer_cert in combination with verify_peer. .RE .IP \fBfail_if_no_peer_cert = true | false\fR .RS 12 If verify is set to verify_peer and set to true the connection will fail if the client does not send a certificate (i.e. an empty certificate). If set to false the server will fail only if an invalid certificate is supplied (an empty certificate is considered valid). .RE .IP \fBdepth = Int\fR .RS 12 Specifies the depth of certificate chains the server is prepared to follow when verifying client certs. For the OTP new SSL implementation it is also used to specify how far the server, i.e. we, shall follow the SSL certificates we present to the clients. Hence, using self-signed certs, we typically need to set this to 0. .RE .IP \fBpassword = String\fR .RS 12 If the private key is encrypted on disc, this password is the 3DES key to decrypt it. .RE .IP \fBciphers = String\fR .RS 12 This string specifies the SSL cipher string. The syntax of the SSL cipher string is an erlang term compliant with the output of ssl:cipher_suites(). .nf ciphers = "[{dhe_rsa,aes_256_cbc,sha}, \\ {dhe_dss,aes_256_cbc,sha}]" .fi .RE .IP \fBsecure_renegotiate = true | false\fR .RS 12 Specifies whether to reject renegotiation attempt that does not live up to RFC 5746. By default \fBsecure_renegotiate\fR is set to false i.e. secure renegotiation will be used if possible but it will fallback to unsecure renegotiation if the peer does not support RFC 5746. .RE .IP \fBclient_renegotiation = true | false\fR .RS 12 Enables or disables the Erlang/OTP SSL application client renegotiation option. Defaults to true. See the \fIssl\fR manual page at http://www.erlang.org/doc/man/ssl.html for more details. \fBWARNING: This option was introduced in the SSL application in Erlang/OTP 18.0, so Yaws ignores it for previous releases.\fR .RE .IP \fBhonor_cipher_order = true | false\fR .RS 12 If true (the default), use the server's preference for cipher selection. If false, use the client's preference. \fBWARNING: This option was introduced in the SSL application in Erlang/OTP 17.0, so Yaws ignores it for previous releases.\fR .RE .IP \fBprotocol_version = ProtocolList\fR .RS 12 Specifies the list of SSL protocols that will be supported. If not set, defaults to all protocols supported by the erlang \fBssl\fR application. For example, to support only TLS versions 1.2, 1.1, and 1: .nf protocol_version = tlsv1.2, tlsv1.1, tlsv1 .fi \fBWARNING: Erlang/OTP R16B01 or higher is required in order to let it work (because of a bug in previous releases).\fR .RE .TP \fB<redirect> ... </redirect>\fR Defines a redirect mapping. The following items are allowed within a matching pair of <redirect> and </redirect> delimiters. We can have a series of redirect rules in one of the formats below: .nf Path = URL Path = code Path = code URL .fi \fBPath\fR must be an url-decoded path beginning with a slash. \fBURL\fR may be either a relative URL (a path beginning with a slash), or an absolute URL. In the first case, the \fIscheme:hostname:port\fR of the current server will be added. All accesses to \fBPath\fR will be redirected to \fBURL/Path\fR (or \fBscheme:hostname:port/URL/Path\fR if \fBURL\fR is relative). \fBURL\fR must be url-encoded. Note that the original path is appended to the redirected URL. For example, assume we have the following redirect configuration: .nf <redirect> /foo = http://www.mysite.org/zapp /bar = /tomato.html </redirect> .fi Assuming this config resides on a site called http://abc.com, we have the following redirects: .nf http://abc.com/foo -> http://www.mysite.org/zapp/foo http://abc.com/foo/test -> http://www.mysite.org/zapp/foo/test http://abc.com/bar -> http://abc.com/tomato.html/bar http://abc.com/bar/x/y/z -> http://abc.com/tomato.html/bar/x/y/z .fi By default, Yaws will perform a 302 redirect. The HTTP status code can be changed using the \fBcode\fR parameter. Note that the status code must be known by Yaws. .RS .IP \[bu] 3 For 3xx status codes, the \fBURL\fR parameter must be present and will be used to build the new location. .IP \[bu] For other status codes (1xx, 2xx, 4xx and 5xx), it can be omitted. In the absence of \fBURL\fR, Yaws will return a generic response with the specified status code. .IP \[bu] Otherwise, the \fBURL\fR parameter must be a relative URL and will be used to customize the response. .RE .RS 7 Sometimes we do not want to have the original path appended to the redirected path. To get that behaviour we specify the config with '==' instead of '='. .nf <redirect> /foo == http://www.mysite.org/zapp /bar = /tomato.html </redirect> .fi Now a request for http://abc.com/foo/x/y/z simply gets redirected to http://www.mysite.org/zapp. This is typically used when we simply want a static redirect at some place in the docroot. When we specify a relative URL as the target for the redirect, the redirect will be to the current http(s) server. .RE .TP \fB<auth> ... </auth>\fR Defines an auth structure. The following items are allowed within a matching pair of <auth> and </auth> delimiters. \fBdocroot = Docroot \fR .RS 12 If a docroot is defined, this auth structure will be tested only for requests in the specified docroot. No docroot configured means all docroots. If two auth structures are defined, one with a docroot and one with no docroot, the first of both overrides the second one for requests in the configured docroot. .RE .IP \fBdir = Dir\fR .RS 12 Makes Dir to be controlled by WWW-authenticate headers. In order for a user to have access to WWW-Authenticate controlled directory, the user must supply a password. The Dir must be specified relative to the docroot. Multiple dir can be used. If no dir is set, the default value, \fI"/"\fR, will be used. .RE .IP \fBrealm = Realm\fR .RS 12 In the directory defined here, the WWW-Authenticate Realm is set to this value. .RE .IP \fBauthmod = AuthMod\fR .RS 12 If an auth module is defined then AuthMod:auth(Arg, Auth) will be called for all access to the directory. The auth/2 function should return one of: true, false, {false, Realm}, {appmod, Mod}. If {appmod, Mod} is returned then a call to Mod:out401(Arg, Auth, Realm) will be used to deliver the content. If errormod_401 is defined, the call to Mod will be ignored. (Mod:out(Arg) is deprecated). This can, for example, be used to implement cookie authentication. The auth() callback would check if a valid cookie header is present, if not it would return {appmod, ?MODULE} and the out401/1 function in the same module would return {redirect_local, "/login.html"}. .RE .IP \fBuser = User:Password\fR .RS 12 Inside this directory, the user User has access if the user supplies the password Password in the popup dialogue presented by the browser. We can obviously have several of these value inside a single <auth> </auth> pair. The usage of User:Password in the actual config file is deprecated as of release 1.51. It is preferred to have the users in a file called \fI.yaws_auth\fR in the actual directory. The .yaws_auth file has to be parseable by \fIfile:consult/1\fR. Each row of the file must contain terms in this form: .nf {User, Password}. .fi where both User and Password should be strings. The .yaws_auth file mechanism is recursive, so any subdirectories of Dir are also automatically protected. The .yaws_auth file is never visible in a dir listing. .RE .IP \fBpam service = \fIpam-service\fR\fR .RS 12 If the item \fBpam\fR is part of the auth structure, Yaws will also try to authenticate the user using "pam" using the pam \fIservice\fR indicated. Usual services are typically found under /etc/pam.d. Usual values are "system-auth" etc. pam authentication is performed by an Erlang port program which is typically installed as suid root by the Yaws install script. .RE .IP \fBallow = all | ListOfHost\fR .RS 12 The \fIallow\fR directive affects which hosts can access an area of the server. Access can be controlled by IP address or IP address range. If all is specified, then all hosts are allowed access, subject to the configuration of the \fIdeny\fR and \fIorder\fR directives. To allow only particular hosts or groups of hosts to access the server, the host can be specified in any of the following formats: \fBA full IP address\fR .nf allow = 10.1.2.3 allow = 192.168.1.104, 192.168.1.205 .fi \fBA network/netmask pair\fR .nf allow = 10.1.0.0/255.255.0.0 .fi \fBA network/nnn CIDR specification\fR .nf allow = 10.1.0.0/16 .fi .RE .IP \fBdeny = all | ListOfHost\fR .RS 12 This directive allows access to the server to be restricted based on IP address. The arguments for the \fIdeny\fR directive are identical to the arguments for the \fIallow\fR directive. .RE .IP \fBorder = Ordering\fR .RS 12 The \fIorder\fR directive, along with \fIallow\fR and \fIdeny\fR directives, controls a three-pass access control system. The first pass processes either all \fIallow\fR or all \fIdeny\fR directives, as specified by the \fIorder\fR directive. The second pass parses the rest of the directives (\fIdeny\fR or \fIallow\fR). The third pass applies to all requests which do not match either of the first two. Ordering is one of (Default value is \fIdeny,allow\fR): .TP \fBallow,deny\fR First, all \fIallow\fR directives are evaluated; at least one must match, or the request is rejected. Next, \fIdeny\fR directives are evaluated. If any matches, the request is rejected. Last, any requests which do not match an \fIallow\fR or a \fIdeny\fR directive are denied by default. .TP \fBdeny,allow\fR First, all \fIdeny\fR directives are evaluated; if any matched, the request is denied unless it also matches an \fIallow\fR directive. Any requests which do not match any \fIallow\fR or \fIdeny\fR directives are permitted. .RE .TP \fB<opaque> ... </opaque>\fR This begins and ends an opaque configuration context for this server, where 'Key = Value' directives can be specified. These directives are ignored by Yaws (hence the name opaque), but can be accessed as a list of tuples \fI{Key,Value}\fR stored in the #sconf.opaque record entry. See also the description of the \fIstart_mod\fR directive. This mechanism can be used to pass data from a surrounding application into the individual .yaws pages. .SH EXAMPLES The following example defines a single server on port 80. .nf logdir = /var/log/yaws <server www.mydomain.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www </server> .fi .PP And this example shows a similar setup but two web servers on the same IP address. .nf logdir = /var/log/yaws <server www.mydomain.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www </server> <server www.funky.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www_funky_org </server> .fi .PP An example with www-authenticate and no access logging at all. .nf logdir = /var/log/yaws <server www.mydomain.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www access_log = false <auth> dir = secret/dir1 realm = foobar user = jonny:verysecretpwd user = benny:thequestion user = ronny:havinganamethatendswithy </auth> </server> .fi .PP An example specifying a user defined module to be called at startup, as well as some user specific configuration. .nf <server www.funky.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www_funky_org start_mod = btt <opaque> mydbdir = /tmp mylogdir = /tmp/log </opaque> </server> .fi .PP An example specifying the GSSAPI/SPNEGO module (authmod_gssapi) to be used for authentication. This module requires egssapi version 0.1~pre2 or later available at http://www.hem.za.org/egssapi/. The Kerberos5 keytab is specified as 'keytab = File' directive in opaque. This keytab should contain the keys of the HTTP service principal, 'HTTP/www.funky.org' in this example. .nf <server www.funky.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www_funky_org start_mod = authmod_gssapi <auth> authmod = authmod_gssapi dir = secret/dir1 </auth> <opaque> keytab = /etc/yaws/http.keytab </opaque> </server> .fi .PP And finally a slightly more complex example with two servers on the same IP, and one SSL server on a different IP. When there are more than one server on the same IP, and they have different names the server must be able to choose one of them if the client doesn't send a Host: header. Yaws will choose the first one defined in the conf file. .nf logdir = /var/log/yaws max_num_cached_files = 8000 max_num_cached_bytes = 6000000 <server www.mydomain.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www </server> <server www.funky.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www_funky_org </server> <server www.funky.org> port = 443 listen = 192.168.128.32 docroot = /var/yaws/www_funky_org <ssl> keyfile = /etc/funky.key certfile = /etc/funky.cert password = gazonk </ssl> </server> .fi .PP Finally an example with virtual directories, vdirs. .nf <server server.domain> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www arg_rewrite_mod = yaws_vdir <opaque> vdir = "/virtual1/ /usr/local/somewhere/notrelated/to/main/docroot" vdir = "/myapp/ /some/other/path can include/spaces" vdir = "/icons/ /usr/local/www/yaws/icons" </opaque> </server> .fi .PP The first defined vdir can then be accessed at or under http://server.domain/virtual1/ or http://server.domain/virtual1 .SH AUTHOR Written by Claes Wikstrom .SH "SEE ALSO" .BR yaws (1) .BR erl (1) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/man/Makefile.am��������������������������������������������������������������������������0000664�0001750�0001750�00000003105�12605311412�012222� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������MANPAGES = yaws.1 yaws.conf.5 yaws_api.5 yaws_soap_lib.5 PDFS = $(MANPAGES:=.pdf) EXTRA_DIST = $(MANPAGES) if !MINGW install-data-local: $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(mandir)/man1 $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(mandir)/man5 $(AM_V_at)$(INSTALL) -m 644 @srcdir@/yaws.1 $(DESTDIR)$(mandir)/man1 $(AM_V_at)$(INSTALL) -m 644 @srcdir@/yaws.conf.5 $(DESTDIR)$(mandir)/man5 $(AM_V_at)$(INSTALL) -m 644 @srcdir@/yaws_api.5 $(DESTDIR)$(mandir)/man5 $(AM_V_at)$(INSTALL) -m 644 @srcdir@/yaws_soap_lib.5 $(DESTDIR)$(mandir)/man5 uninstall-local: $(AM_V_at)rm -f $(DESTDIR)$(mandir)/man1/yaws.1 $(AM_V_at)rm -f $(DESTDIR)$(mandir)/man5/yaws.conf.5 $(AM_V_at)rm -f $(DESTDIR)$(mandir)/man5/yaws_api.5 $(AM_V_at)rm -f $(DESTDIR)$(mandir)/man5/yaws_soap_lib.5 else install-data-local: pdf $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(mandir) $(AM_V_at)$(INSTALL) -m 644 yaws.1.pdf $(DESTDIR)$(mandir) $(AM_V_at)$(INSTALL) -m 644 yaws.conf.5.pdf $(DESTDIR)$(mandir) $(AM_V_at)$(INSTALL) -m 644 yaws_api.5.pdf $(DESTDIR)$(mandir) $(AM_V_at)$(INSTALL) -m 644 yaws_soap_lib.5.pdf $(DESTDIR)$(mandir) uninstall-local: $(AM_V_at)rm -f $(DESTDIR)$(mandir)/yaws.1.pdf $(AM_V_at)rm -f $(DESTDIR)$(mandir)/yaws.conf.5.pdf $(AM_V_at)rm -f $(DESTDIR)$(mandir)/yaws_api.5.pdf $(AM_V_at)rm -f $(DESTDIR)$(mandir)/yaws_soap_lib.5.pdf ## for the win32 build, the rest of us know how to run man pdf-local: $(PDFS) %.pdf: % $(AM_V_GEN)$(MAN) -t $< 2>/dev/null | $(PS2PDF) - $@; clean-local: $(AM_V_at)rm -f $(PDFS) endif # Local Variables: # tab-width: 8 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/LICENSE����������������������������������������������������������������������������������0000664�0001750�0001750�00000002766�12605311412�010434� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Copyright (c) 2006, Claes Wikstrom, klacke@hyber.org All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of "Yaws" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ����������yaws-2.0.2/README.pkg-config������������������������������������������������������������������������0000664�0001750�0001750�00000000447�12605311412�012324� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## ## pkg-config(1) support ## If you have pkg-config installed on your system, you can use it as shown below to obtain information about Yaws: $ pkg-config yaws --modversion 1.80 $ pkg-config yaws --cflags -I/usr/local/lib/yaws/include $ pkg-config yaws --libs -pa /usr/local/lib/yaws/ebin �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/���������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312015�011163� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/Makefile.in����������������������������������������������������������������������0000664�0001750�0001750�00000043271�12605311446�013166� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = scripts DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/make-release.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = make-release CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ EXTRA_DIST = darwin debian freebsd gentoo netbsd openbsd redhat suse \ gen-yaws gen-yaws-conf gen-yaws-generated Subst \ regular-install make-release make-upload \ rebar-pre-script yaws.conf.template yaws.template all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign scripts/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign scripts/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): make-release: $(top_builddir)/config.status $(srcdir)/make-release.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @MINGW_TRUE@uninstall-local: @MINGW_TRUE@install-data-local: clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-local include @top_srcdir@/include.mk @MINGW_FALSE@install-data-local: yaws_script yaws_conf yaws_init_script @MINGW_FALSE@uninstall-local: @MINGW_FALSE@ $(AM_V_at)if diff -U0 $(DESTDIR)$(confdir)/yaws.conf.template \ @MINGW_FALSE@ $(DESTDIR)$(confdir)/yaws.conf; then \ @MINGW_FALSE@ rm -f $(DESTDIR)$(confdir)/yaws.conf; \ @MINGW_FALSE@ else \ @MINGW_FALSE@ echo "Keep modified config file"; \ @MINGW_FALSE@ fi @MINGW_FALSE@ $(AM_V_at)rm -f $(DESTDIR)$(bindir)/yaws @MINGW_FALSE@ $(AM_V_at)rm -f $(DESTDIR)$(sysconfdir)/init.d/yaws @MINGW_FALSE@ $(AM_V_at)rm -f $(DESTDIR)$(sysconfdir)/rc.d/yaws @MINGW_FALSE@ $(AM_V_at)rm -f $(DESTDIR)$(sysconfdir)/systemd/system/yaws.service @MINGW_FALSE@ $(AM_V_at)rm -f $(DESTDIR)$(confdir)/yaws.conf.template @MINGW_FALSE@yaws_script: @MINGW_FALSE@ $(AM_V_GEN) @MINGW_FALSE@ $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(bindir) @MINGW_FALSE@ $(AM_V_at)(cd @srcdir@ && \ @MINGW_FALSE@ YAWSDIR='$(yawsdir)' \ @MINGW_FALSE@ VARDIR='$(localstatedir)' \ @MINGW_FALSE@ ERLBINDIR='$(ERLANG_ERTS_DIR)/bin' \ @MINGW_FALSE@ ERL='$(ERL)' WERL='$(WERL)' \ @MINGW_FALSE@ ./gen-yaws > $(DESTDIR)$(bindir)/yaws) @MINGW_FALSE@ $(AM_V_at)chmod +x $(DESTDIR)$(bindir)/yaws @MINGW_FALSE@yaws_conf: @MINGW_FALSE@ $(AM_V_GEN) @MINGW_FALSE@ $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(confdir); @MINGW_FALSE@ $(AM_V_at)user=$${SUDO_USER:-$$(whoami)}; \ @MINGW_FALSE@ if [ $${user} == 'root' -o $${user} != $$(whoami) ]; then \ @MINGW_FALSE@ PORT=80; \ @MINGW_FALSE@ SSLPORT=443; \ @MINGW_FALSE@ else \ @MINGW_FALSE@ PORT=8000; \ @MINGW_FALSE@ SSLPORT=4443; \ @MINGW_FALSE@ fi; \ @MINGW_FALSE@ (cd @srcdir@ && \ @MINGW_FALSE@ YAWSDIR='$(yawsdir)' \ @MINGW_FALSE@ LOGDIR='$(logdir)' \ @MINGW_FALSE@ VARDIR='$(localstatedir)' \ @MINGW_FALSE@ PORT=$${PORT} \ @MINGW_FALSE@ DOCROOT='$(wwwdir)' \ @MINGW_FALSE@ CERTDIR='$(confdir)' \ @MINGW_FALSE@ SSLPORT=$${SSLPORT} \ @MINGW_FALSE@ ./gen-yaws-conf > $(DESTDIR)$(confdir)/yaws.conf.template) @MINGW_FALSE@ $(AM_V_at)if [ -f "$(DESTDIR)$(confdir)/yaws.conf" ]; then \ @MINGW_FALSE@ echo "* Keeping old config file "; \ @MINGW_FALSE@ else \ @MINGW_FALSE@ echo "* Installing new config file"; \ @MINGW_FALSE@ $(INSTALL) -m 644 $(DESTDIR)$(confdir)/yaws.conf.template \ @MINGW_FALSE@ $(DESTDIR)$(confdir)/yaws.conf; \ @MINGW_FALSE@ fi @MINGW_FALSE@yaws_init_script: @MINGW_FALSE@ $(AM_V_GEN) @MINGW_FALSE@ $(AM_V_at)(cd @srcdir@ && \ @MINGW_FALSE@ DESTDIR='$(DESTDIR)' \ @MINGW_FALSE@ PREFIX='$(prefix)' \ @MINGW_FALSE@ ETCDIR='$(sysconfdir)' \ @MINGW_FALSE@ BINDIR='$(bindir)' \ @MINGW_FALSE@ LOGDIR='$(logdir)' \ @MINGW_FALSE@ YAWSDIR='$(ERLANG_INSTALL_LIB_DIR_yaws)' \ @MINGW_FALSE@ ./regular-install) # Local Variables: # tab-width: 8 # End: # 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: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/gentoo/��������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�012456� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/gentoo/yaws.init�����������������������������������������������������������������0000664�0001750�0001750�00000001546�12605311412�014254� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/sbin/runscript # # Startup script for the Yaws Web Server (for Gentoo Linux) # # config: /etc/conf.d/yaws # # description: yaws - Erlang enabled http server # # use: rc-update add yaws default # yaws=%bindir%/yaws # By default we run with the default id # idopts="--id myserverid" conf="--conf %etcdir%/yaws/yaws.conf" opts="start stop reload restart query" depend() { need net } start() { ebegin "Starting yaws " ${yaws} --daemon --heart ${idopts} ${conf} ${yaws} ${idopts} --wait-started=10 eend $? } stop() { ebegin "Stopping yaws " ${yaws} ${idopts} --stop ${yaws} ${idopts} --wait-stopped=10 eend $? } reload() { ebegin "Reloading yaws " ${yaws} ${idopts} --hup eend $? } query() { ebegin "Querying yaws " ${yaws} ${idopts} --status eend $? } ����������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/suse/����������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�012142� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/suse/yaws.init�������������������������������������������������������������������0000664�0001750�0001750�00000010560�12605311412�013734� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh ### BEGIN INIT INFO # Provides: yaws # Required-Start: $network $remote_fs # Should-Start: $null # Required-Stop: $network $remote_fs # Should-Stop: $null # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Short-Description: A high performance HTTP 1.1 webserver # Description: Yaws is a HTTP high perfomance 1.1 webserver # particularly well suited for dynamic-content # webapplications. ### END INIT INFO YAWS_BIN=%bindir%/yaws ## By default we run with the default id # YAWS_ID_OPTS=--id myserverid conf="--conf %etcdir%/yaws/yaws.conf" test -x $YAWS_BIN || exit 5 # Shell functions sourced from /etc/rc.status: # rc_check check and set local and overall rc status # rc_status check and set local and overall rc status # rc_status -v ditto but be verbose in local rc status # rc_status -v -r ditto and clear the local rc status # rc_failed set local and overall rc status to failed # rc_failed <num> set local and overall rc status to <num><num> # rc_reset clear local rc status (overall remains) # rc_exit exit appropriate to overall rc status # rc_active checks whether a service is activated by symlinks . /etc/rc.status # First reset status of this service rc_reset # Return values acc. to LSB for all commands but status: # 0 - success # 1 - generic or unspecified error # 2 - invalid or excess argument(s) # 3 - unimplemented feature (e.g. "reload") # 4 - insufficient privilege # 5 - program is not installed # 6 - program is not configured # 7 - program is not running # # Note that starting an already running service, stopping # or restarting a not-running service as well as the restart # with force-reload (in case signalling is not supported) are # considered a success. case "$1" in start) echo -n "Starting YAWS" ## Start daemon with startproc(8). If this fails ## the echo return value is set appropriate. # NOTE: startproc returns 0, even if service is # already running to match LSB spec. startproc $YAWS_BIN --daemon --heart $YAWS_ID_OPTS $conf $YAWS_BIN $YAWS_ID_OPTS --wait-started=10 >/dev/null # Remember status and be verbose rc_status -v ;; stop) echo -n "Shutting down YAWS" ## Stop daemon with killproc(8) and if this fails ## set echo the echo return value. startproc $YAWS_BIN $YAWS_ID_OPTS --stop $YAWS_BIN $YAWS_ID_OPTS --wait-stopped=10 >/dev/null # Remember status and be verbose rc_status -v ;; try-restart) ## Stop the service and if this succeeds (i.e. the ## service was running before), start it again. ## Note: try-restart is not (yet) part of LSB (as of 0.7.5) $0 status >/dev/null && $0 restart # Remember status and be quiet rc_status ;; restart) ## Stop the service and regardless of whether it was ## running or not, start it again. $0 stop $0 start # Remember status and be quiet rc_status ;; force-reload) ## Signal the daemon to reload its config. Most daemons ## do this on signal 1 (SIGHUP). ## If it does not support it, restart. echo -n "Force Reload service YAWS" ## if it supports it: $YAWS_BIN $YAWS_ID_OPTS --hup rc_status -v ;; reload) ## Like force-reload, but if daemon does not support ## signalling, do nothing (!) # If it supports signalling: startproc $YAWS_BIN $YAWS_ID_OPTS --hup rc_status -v ;; status) echo -n "Checking for service YAWS: " ## Check status with checkproc(8), if process is running ## checkproc will return with exit status 0. # Return value is slightly different for the status command: # 0 - service running # 1 - service dead, but /var/run/ pid file exists # 2 - service dead, but /var/lock/ lock file exists # 3 - service not running # NOTE: checkproc returns LSB compliant status values. checkproc $YAWS_BIN $YAWS_ID_OPTS --status rc_status -v ;; *) echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}" exit 1 ;; esac rc_exit ������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/debian/��������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�012405� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/debian/yaws.init�����������������������������������������������������������������0000664�0001750�0001750�00000003344�12605311412�014201� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh ### BEGIN INIT INFO # Provides: yaws # Required-Start: $remote_fs $network # Required-Stop: $remote_fs $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Starts Yaws web server # Description: Starts Yaws web server, a high perfomance # HTTP 1.1 webserver written in Erlang. ### END INIT INFO DAEMON=%bindir%/yaws NAME=yaws DESC="Yaws web server" DAEMON_OPTS="--daemon --heart --conf %etcdir%/yaws/yaws.conf" ## By default we run with the default id # YAWS_ID_OPTS=--id myserverid test -x $DAEMON || exit 0 . /lib/lsb/init-functions start() { start-stop-daemon --quiet --exec $DAEMON --start -- \ $DAEMON_OPTS $YAWS_ID_OPTS $DAEMON $YAWS_ID_OPTS --wait-started=10 >/dev/null } stop() { $DAEMON $YAWS_ID_OPTS --stop > /dev/null $DAEMON $YAWS_ID_OPTS --wait-stopped=10 >/dev/null } case "$1" in start) log_daemon_msg "Starting $DESC" "$NAME" start log_end_msg $? ;; stop) log_daemon_msg "Stopping $DESC" "$NAME" stop log_end_msg $? ;; status) $DAEMON $YAWS_ID_OPTS --status > /dev/null && \ log_success_msg "Yaws is running" || \ log_failure_msg "Yaws is not running" ;; reload|force-reload) log_daemon_msg "Reloading $DESC config" "$NAME" $DAEMON $YAWS_ID_OPTS --hup >/dev/null && log_end_msg 0 || log_end_msg 1 ;; restart) log_daemon_msg "Restarting $DESC" "$NAME" stop start log_end_msg $? ;; *) N=%etcdir%/init.d/$NAME echo "Usage: $N {start|stop|status|restart|reload|force-reload}" >&2 exit 1 ;; esac exit 0 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/make-release���������������������������������������������������������������������0000775�0001750�0001750�00000001423�12605311456�013374� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh SRCDIR=/home/klacke/yaws BUILDDIR=/home/klacke/yaws YAWS_VSN=2.0.2 INSTALL_BUILDER=${INSTALL_BUILDER:-/home/klacke/installbuilder-5.4.14} echo packing release ${YAWS_VSN} TAG="yaws-${YAWS_VSN}" NAME_VERSION="yaws-${YAWS_VSN}" # Add/update release tag (cd ${SRCDIR} && git tag -f -a -m "version ${YAWS_VSN}" "$TAG") # Create windows installer (cd ${BUILDDIR} && make mkinstaller INSTALL_BUILDER=${INSTALL_BUILDER} >/dev/null) # Create distribution tarball (cd ${BUILDDIR} && make dist > /dev/null) echo release resides in ${BUILDDIR}/$NAME_VERSION.tar.gz echo release resides in ${BUILDDIR}/Yaws-${YAWS_VSN}-windows-installer.exe echo "To push this do:" #echo "git push origin revs/tags/yaws-${version}:revs/tags/yaws-${version}" echo "ehhh or git push --tags" exit 0 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/gen-yaws-generated���������������������������������������������������������������0000775�0001750�0001750�00000000512�12605311412�014515� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # Used by src/Makefile and scripts/rebar-pre-script to create the # yaws_generated.erl file set -e cat yaws_generated.template | \ ../scripts/Subst %VSN% "${YAWS_VSN}" | \ ../scripts/Subst %VARDIR% "${VARDIR}" | \ ../scripts/Subst %ETCDIR% "${ETCDIR}" exit 0 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/yaws.template��������������������������������������������������������������������0000775�0001750�0001750�00000030674�12605311412�013640� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh yawsdir="%yawsdir%" vardir="%vardir%" erl="%erl%" run_erl="%run_erl%" to_erl="%to_erl%" # erlexec requires HOME to be set, and some distros # run /etc/rc scripts without HOME being set if [ -z "$HOME" ]; then if [ `id -u` = 0 -a -d /root ]; then HOME=/root else HOME=/tmp fi export HOME fi case `uname` in CYGWIN*) yawsdir=`cygpath -m $yawsdir` werl="%werl%" delim=/;; *) delim=/ esac ENV_PGM=`which env` help() { echo "usage: " echo "" echo echo " yaws -i | --interactive -- interactive (no daemon) mode" echo " yaws -w | --winteractive -- cygwin interactive (werl) " echo " yaws --daemon -- daemon mode" echo "" echo "" echo " Auxiliary flags for the daemon: " echo " --id Id -- set system id" echo " --debug -- debug mode" echo " --nodebug -- turn off debug mode" echo " --conf File -- set config file" echo " --tracetraf -- trace traffic" echo " --tracehttp -- trace http traffic" echo " --traceout -- trace output to stdout" echo " --version -- print version" echo " --pa path -- add load path" echo " --mnesiadir dir -- start Mnesia in dir" echo " --proto_dist Mod -- use Mod for distrib" echo " --sname xxx -- start with sname xxx" echo " --name xxx -- start with name xxx" echo " --runmod mod -- call mod:start/0 at startup" echo " --heart -- auto restart yaws if it crashes" echo " --heart-restart=C,T -- allow C heart restarts in T seconds" echo " --erlarg X -- pass argument X to $erl" echo " --setcookie X -- set an erlang cookie" echo " --run_erl X -- use run_erl with pipe-id X" echo " --to_erl X -- connect to pipe-id X" echo " --disable-kpoll -- pass +K false to erlang" echo " --umask umaskval -- set process umask to umaskval" echo "" echo "ctl functions ... " echo " yaws --hup [--id ID] -- hup the daemon, reload conf" echo " yaws --stop [--id ID] -- stop the daemon " echo " yaws --debug-dump [--id ID] -- produce a debug dump " echo " yaws --status [--id ID] -- query the daemon status " echo " yaws --load Modules -- load modules " echo " yaws --ls -- list Yaws nodes and their status" echo " yaws --ctltrace traffic|http -- toggle trace of running daemon" echo " yaws --check [--verbose] [--id ID] YawsFile [IncDirs] -- test compile YawsFile" echo " yaws --configtest File [--verbose] -- test config file" echo " yaws --wait-started[=secs] [--id ID] -- wait for daemon to be ready" echo " yaws --wait-stopped[=secs] [--id ID] -- wait for daemon to be stopped" echo " yaws --stats [--id ID] -- show daemon statistics" exit 1 } debug="" daemon="" interactive="" trace="" conf="" runmod="" sname="" heart="" xpath="" mnesia="" id="" pdist="" erlarg="" kpoll=true call_wait_started="" call_wait_stopped="" check="" checkargs="" configtest="" configtestcmd="" verbose="" program=$0 wait_started() { i=0 count=$1 while [ $i -lt $count ]; do sleep 1 i=`expr $i + 1` idarg="--id ${id:-default}" ${program} ${idarg} --status 2>&1 > /dev/null [ $? = 0 ] && exit 0 done echo "No yaws system responding for id=$id" exit 1 } wait_stopped() { i=0 count=$1 while [ $i -lt $count ]; do sleep 1 i=`expr $i + 1` idarg="--id ${id:-default}" ${program} ${idarg} --status 2>&1 > /dev/null [ $? != 0 ] && exit 0 done echo "Yaws system still responding for id=$id" exit 1 } now=`date -u +%s` restarts=1 starttime=$now if [ "$HEART" = true ]; then # we were restarted by heart, make sure we haven't reached our restart count # if we get $YAWS_HEART_COUNT restarts within $YAWS_HEART_SECS seconds, we # exit completely # if both are 0, disable restart checking and just always restart if [ $YAWS_HEART_COUNT -ne 0 -o $YAWS_HEART_SECS -ne 0 ]; then timediff=`expr $now - $YAWS_HEART_START` if [ $timediff -le $YAWS_HEART_SECS ]; then if [ $YAWS_HEART_RESTARTS -eq $YAWS_HEART_COUNT ]; then echo $YAWS_HEART_COUNT restarts attempted within $YAWS_HEART_SECS seconds, exiting exit 1 else # we haven't reached the restart max count yet, but we're still # within the $YAWS_HEART_SECS second window so increment the counter # but keep the same start time restarts=`expr $YAWS_HEART_RESTARTS + 1` starttime=$YAWS_HEART_START fi fi fi fi HEART_COMMAND="$ENV_PGM HEART=true YAWS_HEART_RESTARTS=$restarts YAWS_HEART_START=$starttime $program" # This loop quotes arguments containing whitespace so they can be passed # properly to the next heart restart for arg in "$@"; do ws=`( set X $arg ; echo $# )` if [ "$ws" -gt 2 ]; then HEART_COMMAND="$HEART_COMMAND '$arg'" else HEART_COMMAND="$HEART_COMMAND $arg" fi done export HEART_COMMAND while [ $# -gt 0 ] do arg=$1 shift; case $arg in -i|--interactive) interactive="true"; debug=" -yaws debug "; daemon="";; -w|--winteractive) interactive="true"; debug=" -yaws debug "; daemon=""; erl=$werl;; -D|--daemon) daemon=" -detached ";; --wait-started=*) call_wait_started=`echo $arg | sed -e 's/--wait-started=//'` num=`expr "$call_wait_started" : "\([0-9]*\)"` if [ "$num" != "$call_wait_started" ]; then echo error: argument to --wait-started is $call_wait_started, not a number exit 1 fi;; --wait-started) call_wait_started=30;; --wait-stopped=*) call_wait_stopped=`echo $arg | sed -e 's/--wait-stopped=//'` num=`expr "$call_wait_stopped" : "\([0-9]*\)"` if [ "$num" != "$call_wait_stopped" ]; then echo error: argument to --wait-stopped is $call_wait_stopped, not a number exit 1 fi;; --wait-stopped) call_wait_stopped=30;; -d|--debug) debug=" -boot start_sasl -yaws debug ";; --nodebug) debug="";; -t|--tracetraf) trace=" -yaws trace traffic ";; -T|--tracehttp) trace=" -yaws trace http ";; -I|--id) id=$1 shift;; -x|--traceout) traceoutput=" -yaws traceoutput ";; --trace) traceoutput=" -yaws traceoutput "; trace=" -yaws trace traffic ";; -M|--mnesiadir) mnesia=" -mnesia dir '\"$1\"' -run mnesia start" shift;; -c|--conf) conf=" -conf $1 " shift;; -pa|--pa) xpath=" $xpath -pa $1 " shift;; -r|--runmod) runmod=" -runmod $1 " shift;; -h|--hup) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl hup";; -s|--stop) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl stop";; -ls|--ls) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl ls";; -S|--status) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl status";; --stats) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl stats";; --running-config) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl running_config";; -load|--load) loadid=${id:-default} $erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl load $* $loadid exit 0;; --debug-dump) ddid=${id:-default} $erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl debug_dump $ddid exit 0;; -j|--ctltrace) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl trace $1" shift;; -v|--version) exec $erl -noshell -pa ${yawsdir}${delim}ebin -s yaws printversion; exit 0;; --sname|-sname) sname=" -sname $1 " shift;; -name|--name) sname=" -name $1 " shift;; --disable-kpoll) kpoll=false;; -heart|--heart) heart=" -heart ";; --heart-restart=*) vals=`echo $arg | sed -e 's/--heart-restart=//'` saveifs="$IFS" IFS=, var='YAWS_HEART_COUNT' for v in $vals; do eval "$var=$v" var='YAWS_HEART_SECS' done num=`expr "$YAWS_HEART_COUNT" : '\([0-9]*\)'` if [ -z "$num" -o "$num" != "$YAWS_HEART_COUNT" ]; then echo error: count argument to --heart-restart is '"'$YAWS_HEART_COUNT'"': not a number exit 1 fi num=`expr "$YAWS_HEART_SECS" : '\([0-9]*\)'` if [ -z "$num" -o "$num" != "$YAWS_HEART_SECS" ]; then echo error: time argument to --heart-restart is '"'$YAWS_HEART_SECS'"': not a number exit 1 fi IFS="$saveifs" heart=" -heart ";; -proto_dist|--proto_dist) pdist=" -proto_dist $1 " shift;; -setcookie|--setcookie) erlarg="$erlarg -setcookie $1 " shift;; -erlarg|--erlarg) erlarg="$erlarg $1 " shift;; -check|--check) check="$erl -noshell -pa ${yawsdir}${delim}ebin $xpath -s yaws_ctl check";; -configtest|--configtest) configtest="$erl -noshell -pa ${yawsdir}${delim}ebin $xpath" configtestcmd=" -s yaws_ctl configtest $1"; shift;; --verbose) verbose=true;; --to_erl) TO_ERL=yes PIPE_DIR="${vardir}/run/yaws/pipe/$1" shift;; --run_erl) RUN_ERL=yes daemon="" PIPE_DIR="${vardir}/run/yaws/pipe/$1" LOG_DIR="${vardir}/log/yaws/erlang-log/$1" shift;; --umask) umask $1 shift;; *) if [ -z "$check" ]; then help else checkargs="$checkargs $arg " fi esac done YAWS_HEART_COUNT=${YAWS_HEART_COUNT:-5} YAWS_HEART_SECS=${YAWS_HEART_SECS:-60} export YAWS_HEART_COUNT YAWS_HEART_SECS [ -n "$call_wait_started" ] && wait_started $call_wait_started [ -n "$call_wait_stopped" ] && wait_stopped $call_wait_stopped if [ -n "$check" ]; then checkid=${id:-default} set $checkargs check="$check $checkid $checkargs" mkdir ${HOME}/.yaws/yaws 2> /dev/null mkdir ${HOME}/.yaws/yaws/$checkid 2> /dev/null if [ -n "$verbose" ]; then out=`exec $check` if [ "$?" = "0" ]; then [ -n "$out" ] && echo "$out" echo "$1" ok exit 0 fi echo "$out" exit 1 else exec $check fi fi if [ -n "$configtest" ]; then if [ -n "$verbose" ]; then exec $configtest $configtestcmd else exec $configtest -eval "error_logger:tty(false)" $configtestcmd fi fi if [ -n "$ex" ]; then [ -n "$id" ] && execid=$id || execid=default exec $ex $execid exit 0 fi if [ -n "$TO_ERL" ]; then $to_erl $PIPE_DIR/ exit 0 fi if [ -n "$RUN_ERL" ]; then if [ ! -d $LOG_DIR ]; then mkdir -p $LOG_DIR fi if [ ! -d $PIPE_DIR ]; then mkdir -p $PIPE_DIR fi RUN_ERL="$run_erl -daemon $PIPE_DIR/ $LOG_DIR" else RUN_ERL="eval" fi if [ -n "$id" ]; then id="-yaws id $id" fi trace="$trace $traceoutput" [ "$run_erl" = "eval" ] && [ -z "$daemon" ] && [ -z "$interactive" ] && help XEC="$daemon $heart +K $kpoll -pa ${yawsdir}${delim}ebin $xpath $sname $pdist $erlarg $debug -run yaws $trace $conf $runmod $mnesia $id" if [ -z "$heart" ] || [ -z "$daemon" ]; then unset HEART_COMMAND fi $RUN_ERL "exec $erl $XEC" ��������������������������������������������������������������������yaws-2.0.2/scripts/openbsd/�������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�012615� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/openbsd/yaws.sh������������������������������������������������������������������0000664�0001750�0001750�00000000456�12605311412�014061� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh daemon="${TRUEPREFIX}/bin/yaws --daemon" daemon_flags="--conf ${SYSCONFDIR}/yaws/yaws.conf" . /etc/rc.d/rc.subr pexp="${LOCALBASE}/lib/erlang/erts.*${TRUEPREFIX}/lib/yaws/ebin -run yaws" rc_reload() { ${rcexec} "${daemon} --hup" } rc_stop() { ${rcexec} "${daemon} --stop" } rc_cmd $1 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/freebsd/�������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�012575� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/freebsd/yaws���������������������������������������������������������������������0000664�0001750�0001750�00000002764�12605311412�013434� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # # Start up for the Yaws daemon. Use this script for FreeBSD versions 9 or greater. # # REQUIRE: DAEMON # PROVIDE: yaws # KEYWORD: shutdown . /etc/rc.subr name=yaws rcvar=yaws_enable command="%bindir%/yaws" yaws_id="default" # By default we run with the default id start_cmd="yaws_start" stop_cmd="yaws_stop" status_cmd="yaws_status" reload_cmd="yaws_reload" command_args="" extra_commands="reload" required_files="%etcdir%/yaws/yaws.conf" yaws_start() { echo -n "Starting Yaws: " ${command} --id ${yaws_id} --daemon --heart --conf %etcdir%/yaws/yaws.conf ${rc_flags} ${command} --id ${yaws_id} --wait-started=10 > /dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "OK" else echo "FAILED" fi return $RETVAL } yaws_stop() { echo -n "Stopping Yaws: " ${command} --id ${yaws_id} --stop > /dev/null ${command} --id ${yaws_id} --wait-stopped=10 > /dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "OK" else echo "FAILED" fi return $RETVAL } yaws_status() { ${command} --id ${yaws_id} --status > /dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "Yaws is running" else echo "Yaws is stopped" fi return $RETVAL } yaws_reload() { echo -n "Reloading Yaws: " ${command} --id ${yaws_id} --hup > /dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "OK" else echo "FAILED" fi return $RETVAL } load_rc_config $name run_rc_command "$1" ������������yaws-2.0.2/scripts/freebsd/yaws.sh������������������������������������������������������������������0000664�0001750�0001750�00000002274�12605311412�014041� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # # Startup script for Yaws. Use this scripts for FreeBSD versions prior to 9. YAWS_BIN=%prefix%/bin/yaws # By default we run with the default id # YAWS_ID=myserverid CONF=%etcdir%/yaws/yaws.conf if [ "x${YAWS_ID}" = x ]; then idarg="" else idarg="--id ${YAWS_ID}" fi start() { echo -n "Starting Yaws: " $yaws ${idarg} --daemon --heart --conf ${conf} > /dev/null $yaws ${idarg} --wait-started=10 > /dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "OK" else echo "FAILED" fi return $RETVAL } stop() { echo -n "Stopping Yaws: " $yaws ${idarg} --stop > /dev/null $yaws ${idarg} --wait-stopped=10 > /dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "OK" else echo "FAILED" fi return $RETVAL } reload() { echo -n "Reloading Yaws: " $yaws ${idarg} --hup > /dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "OK" else echo "FAILED" fi return $RETVAL } status() { $yaws ${idarg} --status > /dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "Yaws is running" else echo "Yaws is stopped" fi return $RETVAL } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/yaws.conf.template���������������������������������������������������������������0000664�0001750�0001750�00000012073�12605311412�014552� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ # conf for yaws # First we have a set of globals that apply to all virtual servers # This is the directory where all logfiles for # all virtual servers will be written. logdir = %logdir% # These are the paths to directories where additional # beam code can be placed. The daemon will add these # directories to its search path. ebin_dir = %yawsdir%/examples/ebin # This is a directory where application specific .hrl # files can be placed. Application-specific .yaws code can # then include these .hrl files. include_dir = %yawsdir%/examples/include # Set this to an integer value to control # max number of connections from clients into the server. max_connections = nolimit # Normally, yaws does not restrict the number of times a connection is # kept alive using keepalive. Setting this parameter to an integer X # will ensure that connections are closed once they have been used X times. # This can be a useful to guard against long running connections # collecting too much garbage in the Erlang VM. keepalive_maxuses = nolimit # Override the garbage collection option parameters for processes # that handle new connections. Useful for systems expecting long-lived # connections that handle a lot of data. The default value is Erlang's # default. Valid options are {fullsweep_after, X} and/or {min_heap_size, Y} where # X and Y are integers. See Erlang's erlang:spawn_opt/4 function for more # details. The value type is a quoted string containing an Erlang proplist or # the atom undefined. process_options = "[]" # Set the size of the cached acceptor process pool. The value must be an # integer greater than or equal to 0. The default pool size is 8. Setting # the pool size to 0 effectively disables the pool. #acceptor_pool_size = 8 # This is a debug variable, possible values are http | traffic | false # It is also possible to set the trace (possibly to the tty) while # invoking yaws from the shell as in # yaws -i -T -x (see man yaws). trace = false # Enable this if we want to use the old OTP ssl implementation # OTP R13B03 is known to work with this flag set to false (default). use_old_ssl = false # It is possible to have yaws start additional application-specific code at # startup. Set runmod to the name of the module you want yaws to start. It # assumes the module has an exported function start/0. To have multiple # runmods just add more "runmod = xyz" lines. # # runmod = mymodule # By default yaws will copy the erlang error_log and # append it to a wrap log called report.log (in the logdir). # This feature can be turned off. This would typically # be the case when yaws runs within another larger app. copy_error_log = true # Logs are wrap logs log_wrap_size = 1000000 # Possibly resolve all hostnames in logfiles so webalizer # can produce the nice geography piechart log_resolve_hostname = false # Fail completely or not if yaws fails to bind a listen socket. fail_on_bind_err = true # If HTTP auth is used, it is possible to have a specific # auth log. As of release 1.90 the global auth_log is # deprecated and ignored. Now, this variable must be set in # server part #auth_log = true # When we're running multiple yaws systems on the same # host, we need to give each yaws system an individual # name. Yaws will write a number of runtime files under # ${HOME}/.yaws/yaws/${id} # The default value is "default" # If we're not planning to run multiple webservers on the # same host it's much better to leave this value unset since # then all the ctl function (--stop et.el) work without having # to supply the id. # # id = myname # Earlier versions of Yaws picked the first virtual host # in a list of hosts with the same IP/PORT when the Host: # header doesn't match any name on any Host. # This is often nice in testing environments but not # acceptable in real-world hosting scenarios; # think http://porn.bigcompany.com pick_first_virthost_on_nomatch = true # If the HTTP client session is to be kept alive, wait this many # milliseconds for a new request before timing out the connection. Note # that infinity is a valid value but it's not recommended. keepalive_timeout = 30000 # Now, a set of virtual servers. # The examples below first show two virthosted servers on the same IP (0.0.0.0) # in this case, but an explicit IP can be given as well. <server *> port = %port% listen = 0.0.0.0 docroot = %docroot% auth_log = true appmods = <cgi-bin, yaws_appmod_cgi> </server> <server localhost> port = %port% listen = 0.0.0.0 docroot = %tmpdir% dir_listings = true auth_log = true statistics = true <auth> realm = foobar dir = / user = foo:bar user = baz:bar </auth> </server> # Now an SSL server <server *> port = %sslport% docroot = %tmpdir% listen = 0.0.0.0 dir_listings = true auth_log = true <ssl> keyfile = %certdir%/yaws-key.pem certfile = %certdir%/yaws-cert.pem dhfile = %certdir%/dhparams.pem depth = 0 </ssl> </server> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/regular-install������������������������������������������������������������������0000775�0001750�0001750�00000010120�12605311412�014130� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh install -d ${DESTDIR}${ETCDIR} install -d ${DESTDIR}${LOGDIR} # Start by detecting if systemd is used (which systemctl && systemctl list-units) >/dev/null 2>&1 if [ $? = 0 ]; then install -d ${DESTDIR}${ETCDIR}/systemd/system/ sed -e "s;%prefix%;${PREFIX};g" \ -e "s;%etcdir%;${ETCDIR};g" \ -e "s;%bindir%;${BINDIR};g" \ systemd/yaws.service > ${DESTDIR}${ETCDIR}/systemd/system/yaws.service exit 0 fi # Else, looking at distro-specific files os=$( uname -s ) which lsb_release >/dev/null 2>&1 if [ $? = 0 ]; then os=$( lsb_release -si ) elif [ -f /etc/os-release ]; then . /etc/os-release os=${ID} elif [ -f /etc/arch-release ]; then os="arch" elif [ -f /etc/gentoo-release ]; then os="gentoo" elif [ -f /etc/fedora-release ]; then os="fedora" elif [ -f /etc/centos-release ]; then os="centos" elif [ -f /etc/redhat-release ]; then os="redhat" elif [ -f /etc/debian_version ]; then os="debian" elif [ -f /etc/SuSE-release ]; then os="suse" elif [ $os = "Darwin" -a $(id -u) = 0 ]; then os="darwin" elif [ $os = "FreeBSD" ]; then os="freebsd" elif [ $os = "NetBSD" ]; then os="netbsd" else os="Unknown" fi case $(printf $os | tr '[:upper:]' '[:lower:]') in debian | ubuntu) install -d ${DESTDIR}${ETCDIR}/init.d sed -e "s;%prefix%;${PREFIX};g" \ -e "s;%etcdir%;${ETCDIR};g" \ -e "s;%bindir%;${BINDIR};g" \ debian/yaws.init > ${DESTDIR}${ETCDIR}/init.d/yaws chmod +x ${DESTDIR}${ETCDIR}/init.d/yaws ;; gentoo) # seems gentoo don't like to be installed in /usr/local/etc since # # /sbin/runscript still reads /etc/conf.d install -d ${DESTDIR}${ETCDIR}/init.d install -d ${DESTDIR}${ETCDIR}/conf.d sed -e "s;%prefix%;${PREFIX};g" \ -e "s;%etcdir%;${ETCDIR};g" \ -e "s;%bindir%;${BINDIR};g" \ gentoo/yaws.init > ${DESTDIR}${ETCDIR}/init.d/yaws chmod +x ${DESTDIR}${ETCDIR}/init.d/yaws ;; redhat | fedora | centos) install -d ${DESTDIR}${ETCDIR}/init.d sed -e "s;%prefix%;${PREFIX};g" \ -e "s;%etcdir%;${ETCDIR};g" \ -e "s;%bindir%;${BINDIR};g" \ redhat/yaws.init > ${DESTDIR}${ETCDIR}/init.d/yaws chmod +x ${DESTDIR}${ETCDIR}/init.d/yaws ;; *suse*) install -d ${DESTDIR}${ETCDIR}/init.d sed -e "s;%prefix%;${PREFIX};g" \ -e "s;%etcdir%;${ETCDIR};g" \ -e "s;%bindir%;${BINDIR};g" \ suse/yaws.init > ${DESTDIR}${ETCDIR}/init.d/yaws chmod +x ${DESTDIR}${ETCDIR}/init.d/yaws ;; darwin) startupdir="/Library/StartupItems/Yaws" if [ ! -e ${startupdir} ]; then mkdir ${startupdir}; elif [ ! -d ${startupdir} ]; then echo "${startupdir} exists but is not a directory, bailing out ..." exit 1 fi sed -e "s;%prefix%;${PREFIX};g" \ -e "s;%etcdir%;${ETCDIR};g" \ -e "s;%bindir%;${BINDIR};g" \ darwin/Yaws.StartupItem > ${startupdir}/Yaws chmod +x ${startupdir}/Yaws cp darwin/Yaws.plist ${startupdir}/StartupParameters.plist # MacOS is particular about the ownership of startup items. chown -R root:wheel ${startupdir} ;; freebsd) install -d ${DESTDIR}${ETCDIR}/rc.d sed -e "s;%prefix%;${PREFIX};g" \ -e "s;%etcdir%;${ETCDIR};g" \ -e "s;%bindir%;${BINDIR};g" \ freebsd/yaws > ${DESTDIR}${ETCDIR}/rc.d/yaws chmod +x ${DESTDIR}${ETCDIR}/rc.d/yaws ;; netbsd) sed -e "s;%prefix%;${PREFIX};g" \ -e "s;%etcdir%;${ETCDIR};g" \ -e "s;%bindir%;${BINDIR};g" \ netbsd/yaws.sh > ${DESTDIR}${ETCDIR}/rc.d/yaws chmod +x /etc/rc.d/yaws ;; *) install -d ${DESTDIR}${ETCDIR} echo "Don't know how to make /etc/init scripts for this system" echo "possibly add ${PREFIX}/bin/yaws --daemon --heart to your /etc/rc.local manually" ;; esac exit 0 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/darwin/��������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�012447� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/darwin/Yaws.plist����������������������������������������������������������������0000664�0001750�0001750�00000000306�12605311412�014366� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ Description = "Yaws web server"; Provides = ("Yaws"); Requires = ("DirectoryServices"); Uses = ("Disks", "NFS", "Network Time"); OrderPreference = "None"; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/darwin/README��������������������������������������������������������������������0000664�0001750�0001750�00000001154�12605311412�013250� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Yaws startup on MacOS X / Darwin Doing `make install' as root will create a `Yaws' StartupItem in /Library/StartupItems. By default, yaws startup is disabled. To enable it, edit (as root) /etc/hostconfig and add the line YAWS=-YES- Yaws startup can be disabled by changing the line to YAWS=-NO- Yaws will start automatically on reboot. You can manually test the startup without rebooting by issuing the command (as root) in a terminal window $ SystemStarter start Yaws Stop the server by issuing: $ SystemStarter stop Yaws Reload the server with the command $ SystemStarter restart Yaws ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/darwin/Yaws.StartupItem����������������������������������������������������������0000664�0001750�0001750�00000001532�12605311412�015516� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh ## # Yaws HTTP Server ## . /etc/rc.common yaws=%bindir%/yaws lockdir=/var/spool/lock #yawsid_opts='--id myserverid' conf="--conf %etcdir%/yaws/yaws.conf" StartService () { if [ "${YAWS:=-NO-}" = "-YES-" ]; then ConsoleMessage "Starting yaws http daemon" HOME=/tmp $yaws ${yawsid_opts} --daemon --heart ${conf} HOME=/tmp $yaws ${yawsid_opts} --wait-started=10 >/dev/null RETVAL=$? [ $RETVAL = 0 ] fi } StopService () { ConsoleMessage "Stopping yaws http daemon" HOME=/tmp $yaws ${yawsid_opts} --stop HOME=/tmp $yaws ${yawsid_opts} --wait-stopped=10 >/dev/null } RestartService () { if [ "${YAWS:=-NO-}" = "-YES-" ]; then ConsoleMessage "Restarting yaws http daemon" HOME=/tmp $yaws ${yawsid_opts} --hup else StopService fi } RunService "$1" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/netbsd/��������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�012442� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/netbsd/yaws.sh�������������������������������������������������������������������0000664�0001750�0001750�00000003154�12605311412�013704� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # # # PROVIDE: yaws # REQUIRE: DAEMON # # You will need to set some variables in /etc/rc.conf to start Yaws: # # yaws=YES # yaws_flags="" # yaws_id="" # if [ -f /etc/rc.subr ]; then . /etc/rc.subr fi name="yaws" rcvar=$name yaws_command="%bindir%/${name}" required_files="%etcdir%/yaws/yaws.conf" start_cmd="yaws_start" stop_cmd="yaws_stop" status_cmd="yaws_status" reload_cmd="yaws_reload" extra_commands="reload status" if [ -n "$yaws_id" ] then yaws_id="--id $yaws_id" fi : ${yaws_flags:=--heart} yaws_start() { echo -n "Starting Yaws: " $yaws_command $yaws_id $yaws_flags --daemon --conf %etcdir%/yaws/yaws.conf >/dev/null $yaws_command $yaws_id --wait-started=10 >/dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "OK" else echo "FAILED" fi return $RETVAL } yaws_stop() { echo -n "Stopping Yaws: " $yaws_command $yaws_id --stop >/dev/null $yaws_command $yaws_id --wait-stopped=10 >/dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "OK" else echo "FAILED" fi return $RETVAL } yaws_status() { $yaws_command $yaws_id --status >/dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "Yaws is running" else echo "Yaws is stopped" fi return $RETVAL } yaws_reload() { echo -n "Reloading Yaws: " $yaws_command $yaws_id --hup >/dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "OK" else echo "FAILED" fi return $RETVAL } if [ -f /etc/rc.subr -a -f /etc/rc.conf ]; then load_rc_config $name run_rc_command "$1" else yaws_start fi ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/gen-yaws-conf��������������������������������������������������������������������0000775�0001750�0001750�00000000762�12605311412�013513� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # Used by scripts/Makefile and scripts/rebar-pre-script to create # the yaws.conf file set -e cat yaws.conf.template | \ ./Subst %yawsdir% "$YAWSDIR" | \ ./Subst %logdir% "$LOGDIR" | \ ./Subst %vardir% "$VARDIR" | \ ./Subst %port% $PORT | \ ./Subst %docroot% "$DOCROOT" | \ ./Subst %tmpdir% "${TMPDIR:-/tmp}" | \ ./Subst %certdir% "$CERTDIR" | \ ./Subst %sslport% $SSLPORT exit 0 ��������������yaws-2.0.2/scripts/make-upload����������������������������������������������������������������������0000775�0001750�0001750�00000000764�12605311412�013237� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # This is make it a wee bit more convenient for # me to publish the tar balls # set -x if [ $# != 1 ]; then echo 'usage: make-upload <tarball>' exit 1 fi echo "cd incoming " > /tmp/cmds.$$ echo "put $1 " >> /tmp/cmds.$$ ncftp -u anonymous -p klacke@hyber.org upload.sourceforge.net < /tmp/cmds.$$ rm /tmp/cmds.$$ echo "Now login at sourceforge at go the page" echo "http://sourceforge.net/project/admin/editpackages.php?group_id=45637" echo "and create the new package ... " ������������yaws-2.0.2/scripts/Subst����������������������������������������������������������������������������0000775�0001750�0001750�00000000177�12605311412�012136� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh p=$1 if [ `uname -a | fgrep -c Cygwin` != 0 ]; then d=`cygpath -m "$2"` else d=$2 fi sed -e "s;$p;$d;g" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/gen-yaws�������������������������������������������������������������������������0000775�0001750�0001750�00000000702�12605311412�012562� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # Used by scripts/Makefile and scripts/rebar-pre-script to generate # the yaws execution script set -e cat yaws.template | \ ./Subst %yawsdir% "${YAWSDIR}" | \ ./Subst %vardir% "${VARDIR}" | \ ./Subst %run_erl% "${ERLBINDIR}/run_erl" | \ ./Subst %to_erl% "${ERLBINDIR}/to_erl" | \ ./Subst %erl% "${ERL}" | \ ./Subst %werl% "${WERL}" exit 0 ��������������������������������������������������������������yaws-2.0.2/scripts/make-release.in������������������������������������������������������������������0000664�0001750�0001750�00000001407�12605311412�013770� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh SRCDIR=@abs_top_srcdir@ BUILDDIR=@abs_top_builddir@ YAWS_VSN=@YAWS_VSN@ INSTALL_BUILDER=${INSTALL_BUILDER:-@INSTALL_BUILDER@} echo packing release ${YAWS_VSN} TAG="yaws-${YAWS_VSN}" NAME_VERSION="yaws-${YAWS_VSN}" # Add/update release tag (cd ${SRCDIR} && git tag -f -a -m "version ${YAWS_VSN}" "$TAG") # Create windows installer (cd ${BUILDDIR} && make mkinstaller INSTALL_BUILDER=${INSTALL_BUILDER} >/dev/null) # Create distribution tarball (cd ${BUILDDIR} && make dist > /dev/null) echo release resides in ${BUILDDIR}/$NAME_VERSION.tar.gz echo release resides in ${BUILDDIR}/Yaws-${YAWS_VSN}-windows-installer.exe echo "To push this do:" #echo "git push origin revs/tags/yaws-${version}:revs/tags/yaws-${version}" echo "ehhh or git push --tags" exit 0 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/redhat/��������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�012432� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/redhat/yaws.init�����������������������������������������������������������������0000775�0001750�0001750�00000003455�12605311412�014234� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash # # Startup script for the Yaws Web Server # # config: /etc/yaws.conf # # chkconfig: 2345 65 35 # description: yaws - Erlang enabled http server # use "/sbin/chkconfig --add yaws" to install # Source function library. . /etc/rc.d/init.d/functions yaws=%bindir%/yaws prog=yaws heart=--heart # # Default yawsid is "default". If you change this to another ID, # be sure to also uncomment the yawsid_opts line just below. # yawsid=default #yawsid_opts="--id $yawsid" conf="--conf %etcdir%/yaws/yaws.conf" start() { echo -n $"Starting $prog: " $yaws ${yawsid_opts} --daemon ${heart} ${conf} $yaws ${yawsid_opts} --wait-started=10 >/dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo_success else echo_failure fi echo return $RETVAL } stop() { echo -n $"Stopping $prog: " $yaws ${yawsid_opts} --stop >/dev/null $yaws ${yawsid_opts} --wait-stopped=10 >/dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo_success else echo_failure fi echo return $RETVAL } reload() { echo -n $"Reloading $prog: " $yaws ${yawsid_opts} --hup >/dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo_success else echo_failure fi echo return $RETVAL } status() { $yaws ${yawsid_opts} --status >/dev/null RETVAL=$? if [ $RETVAL = 0 ]; then echo "$prog is running..." else echo "$prog is stopped..." fi return $RETVAL } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) status ;; restart) stop start ;; reload) reload ;; *) echo $"Usage: $prog {start|stop|restart|reload|status}" exit 1 esac exit $RETVAL �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/Makefile.am����������������������������������������������������������������������0000664�0001750�0001750�00000004511�12605311412�013140� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include @top_srcdir@/include.mk EXTRA_DIST = darwin debian freebsd gentoo netbsd openbsd redhat suse \ gen-yaws gen-yaws-conf gen-yaws-generated Subst \ regular-install make-release make-upload \ rebar-pre-script yaws.conf.template yaws.template if !MINGW install-data-local: yaws_script yaws_conf yaws_init_script uninstall-local: $(AM_V_at)if diff -U0 $(DESTDIR)$(confdir)/yaws.conf.template \ $(DESTDIR)$(confdir)/yaws.conf; then \ rm -f $(DESTDIR)$(confdir)/yaws.conf; \ else \ echo "Keep modified config file"; \ fi $(AM_V_at)rm -f $(DESTDIR)$(bindir)/yaws $(AM_V_at)rm -f $(DESTDIR)$(sysconfdir)/init.d/yaws $(AM_V_at)rm -f $(DESTDIR)$(sysconfdir)/rc.d/yaws $(AM_V_at)rm -f $(DESTDIR)$(sysconfdir)/systemd/system/yaws.service $(AM_V_at)rm -f $(DESTDIR)$(confdir)/yaws.conf.template yaws_script: $(AM_V_GEN) $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(bindir) $(AM_V_at)(cd @srcdir@ && \ YAWSDIR='$(yawsdir)' \ VARDIR='$(localstatedir)' \ ERLBINDIR='$(ERLANG_ERTS_DIR)/bin' \ ERL='$(ERL)' WERL='$(WERL)' \ ./gen-yaws > $(DESTDIR)$(bindir)/yaws) $(AM_V_at)chmod +x $(DESTDIR)$(bindir)/yaws yaws_conf: $(AM_V_GEN) $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(confdir); $(AM_V_at)user=$${SUDO_USER:-$$(whoami)}; \ if [ $${user} == 'root' -o $${user} != $$(whoami) ]; then \ PORT=80; \ SSLPORT=443; \ else \ PORT=8000; \ SSLPORT=4443; \ fi; \ (cd @srcdir@ && \ YAWSDIR='$(yawsdir)' \ LOGDIR='$(logdir)' \ VARDIR='$(localstatedir)' \ PORT=$${PORT} \ DOCROOT='$(wwwdir)' \ CERTDIR='$(confdir)' \ SSLPORT=$${SSLPORT} \ ./gen-yaws-conf > $(DESTDIR)$(confdir)/yaws.conf.template) $(AM_V_at)if [ -f "$(DESTDIR)$(confdir)/yaws.conf" ]; then \ echo "* Keeping old config file "; \ else \ echo "* Installing new config file"; \ $(INSTALL) -m 644 $(DESTDIR)$(confdir)/yaws.conf.template \ $(DESTDIR)$(confdir)/yaws.conf; \ fi yaws_init_script: $(AM_V_GEN) $(AM_V_at)(cd @srcdir@ && \ DESTDIR='$(DESTDIR)' \ PREFIX='$(prefix)' \ ETCDIR='$(sysconfdir)' \ BINDIR='$(bindir)' \ LOGDIR='$(logdir)' \ YAWSDIR='$(ERLANG_INSTALL_LIB_DIR_yaws)' \ ./regular-install) endif # Local Variables: # tab-width: 8 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/scripts/rebar-pre-script�����������������������������������������������������������������0000775�0001750�0001750�00000007020�12605311412�014211� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh SCRIPT=`basename $0` SCRIPTDIR=`dirname $0` YAWS_DIR=`cd ${SCRIPTDIR}/.. && pwd` . ${YAWS_DIR}/vsn.mk YAWS_VSN=${VSN-$YAWS_VSN} YAWS_ETCDIR=${ETCDIR-$YAWS_DIR/etc} YAWS_BINDIR=${EXECDIR-$YAWS_DIR/bin} # BINDIR is already set by rebar YAWS_VARDIR=${VARDIR-$YAWS_DIR/var} YAWS_LOGDIR=${LOGDIR-$YAWS_DIR/yaws_logs} ERL_BIN=`which erl` ERL_BIN_DIR=${ERL_BIN%/erl} YAWS_ERLBINDIR=${ERLBINDIR-$ERL_BIN_DIR} ERL_BIN=$YAWS_ERLBINDIR/erl WERL_BIN=$YAWS_ERLBINDIR/werl # Use a function for error exit instead of set -e so we can conditionally # remove files before exiting. If this were bash we could trap ERR but # Bourne shell doesn't support that portably. fail() { [ -n "$@" ] && rm -f "$@" exit 1 } keep_or_replace() { if [ -f "$1" ] && cmp -s "$1" "$2"; then rm -f "$2" return 0 else mv "$2" "$1" || fail "$2" return 1 fi } ## handle clean command and exit if [ "$1" = clean ]; then rm -f ${YAWS_DIR}/src/mime_types.erl \ ${YAWS_DIR}/src/yaws_generated.erl exit 0 fi ## Create required directory [ -d "$YAWS_ETCDIR" ] || mkdir "$YAWS_ETCDIR" || fail [ -d "$YAWS_ETCDIR/yaws" ] || mkdir "$YAWS_ETCDIR/yaws" || fail [ -d "$YAWS_BINDIR" ] || mkdir "$YAWS_BINDIR" || fail [ -d "$YAWS_VARDIR" ] || mkdir "$YAWS_VARDIR" || fail [ -d "$YAWS_LOGDIR" ] || mkdir "$YAWS_LOGDIR" || fail [ -d "${YAWS_VARDIR}/yaws" ] || mkdir "${YAWS_VARDIR}/yaws" || fail [ -d "${YAWS_VARDIR}/yaws/ebin" ] || mkdir "${YAWS_VARDIR}/yaws/ebin" || fail ## generate yaws_generated.erl module cd ${YAWS_DIR}/src || fail tmpgen=`mktemp /tmp/${SCRIPT}.XXXXXX` || fail YAWS_VSN="${YAWS_VSN}" VARDIR="${YAWS_VARDIR}" ETCDIR="${YAWS_ETCDIR}" \ ${YAWS_DIR}/scripts/gen-yaws-generated >$tmpgen || fail keep_or_replace ${YAWS_DIR}/src/yaws_generated.erl $tmpgen ## generate mime_types.erl module cd ${YAWS_DIR}/src || fail need_mime=yes if [ -f mime_types.erl ]; then need_mime=`find mime_type_c.erl -newer mime_types.erl -print` fi if [ -n "$need_mime" ]; then erlc -o ${YAWS_DIR}/ebin yaws.erl || fail erlc -o ${YAWS_DIR}/ebin yaws_generated.erl || fail erlc -o ${YAWS_DIR}/ebin mime_type_c.erl || fail erl -pa ${YAWS_DIR}/ebin -noshell -s mime_type_c generate || fail mime_types.erl rm ${YAWS_DIR}/ebin/yaws.beam ${YAWS_DIR}/ebin/yaws_generated.beam ${YAWS_DIR}/ebin/mime_type_c.beam fi ## generate yaws scripts cd ${YAWS_DIR}/scripts tmpgen=`mktemp /tmp/${SCRIPT}.XXXXXX` || fail YAWSDIR="${YAWS_DIR}" VARDIR="${YAWS_VARDIR}" ERLBINDIR="${YAWS_ERLBINDIR}" \ ERL="${ERL_BIN}" WERL="${WERL_BIN}" \ ${YAWS_DIR}/scripts/gen-yaws > $tmpgen || fail chmod +x $tmpgen echo "--- Installed yaws script at ${YAWS_BINDIR}" keep_or_replace ${YAWS_BINDIR}/yaws $tmpgen ## generate default yaws configuration cd ${YAWS_DIR}/scripts tmpgen=`mktemp /tmp/${SCRIPT}.XXXXXX` || fail YAWSDIR="${YAWS_DIR}" LOGDIR="${YAWS_LOGDIR}" VARDIR="${YAWS_VARDIR}" \ PORT=8000 DOCROOT="${YAWS_DIR}/www" CERTDIR="${YAWS_DIR}/ssl" SSLPORT=4443 \ ${YAWS_DIR}/scripts/gen-yaws-conf > $tmpgen if [ -f "${YAWS_ETCDIR}/yaws/yaws.conf" ]; then echo "--- Will not overwrite ${YAWS_ETCDIR}/yaws/yaws.conf" keep_or_replace ${YAWS_ETCDIR}/yaws/yaws.conf.template $tmpgen else echo "--- Installing local config file at ${YAWS_ETCDIR}/yaws" keep_or_replace ${YAWS_ETCDIR}/yaws/yaws.conf $tmpgen fi exit 0 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/README.md��������������������������������������������������������������������������������0000664�0001750�0001750�00000011050�12605311412�010670� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is Yaws, a webserver for dynamic content written in Erlang. [![Travis build Status](https://travis-ci.org/klacke/yaws.svg?branch=master)](https://travis-ci.org/klacke/yaws) Prepare build ------------- Get and install an Erlang system (http://www.erlang.org). **To compile Yaws, Erlang/OTP R14B02 or higher is required.** **For SSL-enabled instances, Erlang/OTP R16B01 or higher is required in order to allow only specific protocol versions.** If you've cloned the source from github and you want to build using autotools, note there is no ./configure script in the source, so create one: $> autoreconf -fi Install build dependencies. Required packages to compile Yaws are (based on debian packages): * build-essential * autoconf/automake/libtool * erlang - Required apps: * erlang-{kernel/stdlib/sasl/erts} * erlang-compiler * erlang-crypto * erlang-xmerl * libpam0g-dev To build the documentation (optional), you also need to install: * texlive-latex-base * texlive-latex-recommended * texlive-fonts-recommended * texlive-font-utils * texlive-extra-utils * ghostscript On Ubuntu/debian this is pretty much equal to: $> apt-get build-dep yaws Finally, to run the testsuites, yaws need to install: * git * wget * curl * erlang-eunit * erlang-inets * erlang-mnesia * erlang-ssl * cadaver Build ----- You can build using rebar: $> rebar get-deps compile or via autotools: $> ./configure --prefix=/usr/local If using rebar, you'll get a "local installation" with Yaws script in ./bin and the Yaws configuration file in ./etc/yaws. If using autotools, the build will be configured by default for installation under /usr/local. For more information about installation directories and other supported options, see the configure help. Useful options are: --with-defaultcharset=CHARSET specify default charset, i.e UTF-8 --with-extrainclude=DIR dir to include if e.g. pam is installed in some odd place --with-erlang=PREFIX prefix where Erlang is installed (optional) Note to packagers (rpm, deb ...) All install targets support the DESTDIR variable. Thus, if we do $> ./configure --prefix=/usr; make we can subsequently do: $> make install DESTDIR=/foo/bar All Yaws files will be installed under DESTDIR, but all code will assume Yaws should be installed under /usr. Main make targets: * all : compile Yaws * debug : compile Yaws with debug flags * clean : remove files produced by all or debug target * install : do a proper install of Yaws * doc or docs : build the documentation * check or test : launch tests * cleantest : remove files produced by check target * dialyzer : run dialyzer on Yaws * mkinstaller : build an installer for windows * cleaninstaller: remove files produced by mkinstaller target * apps : compile Yaws applications (chat,mail,wiki,yapp) * cleanapps : remove files produced by apps target * installapps : install Yaws applications * fullinstall : install + installapps * fullclean : clean + cleantest + cleanapps + cleaninstaller Test your build --------------- With autotools, to test the build, you should install it somewhere: $> ./configure --prefix=$PWD/_inst && make install $> $PWD/_inst/bin/yaws -i If you used rebar to compile Yaws, you can alternatively start Yaws with $> ./bin/yaws -i Either approach will start a webserver at http://0.0.0.0:8000 Terminate through ^C, or ^G followed by q, or > init:stop() NOTE: If you've used rebar to build the system, none of the following directions apply. With rebar only "local installations" are supported. Install and run --------------- NOTE: following commands may require root privileges, depending of the installation prefix. Just run: $> make install Then, to run Yaws, you should use its script: $> ${bindir}/yaws -i This starts an interactive system. With the default yaws.conf file, this will create a webserver at http://${host} and one at https://${host}. You can adapt Yaws configuration by editing '${sysconfig}/yaws/yaws.conf'. Daemonize Yaws -------------- Start it using '--daemon' and '--heart' options: $> ${bindir}/yaws --daemon --heart This will start a daemon (--daemon) which will be autorestarted when/if it crashes or hangs (--heart). Also, for most unices, we create proper start scripts in ${sysconfdir}/init.d Example: Here is how I compile/start the yaws system that runs at http://yaws.hyber.org (Ubuntu server system) $> autoreconf -fi $> ./configure --sysconfdir=/etc $> make && make install $> /etc/init.d/yaws start ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ac-aux/����������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312014�010651� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ac-aux/missing���������������������������������������������������������������������������0000755�0001750�0001750�00000015330�12605311445�012177� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. # 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 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to <bug-automake@gnu.org>." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ac-aux/ar-lib����������������������������������������������������������������������������0000755�0001750�0001750�00000013302�12605311445�011671� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2012-03-01.08; # UTC # Copyright (C) 2010-2013 Free Software Foundation, Inc. # Written by Peter Rosin <peda@lysator.liu.se>. # # 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 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to <bug-automake@gnu.org> or send patches to # <automake-patches@gnu.org>. # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <<EOF Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...] Members may be specified in a file named with @FILE. EOF exit $? ;; -v | --v*) echo "$me, version $scriptversion" exit $? ;; esac if test $# -lt 3; then func_error "you must specify a program, an action and an archive" fi AR=$1 shift while : do if test $# -lt 2; then func_error "you must specify a program, an action and an archive" fi case $1 in -lib | -LIB \ | -ltcg | -LTCG \ | -machine* | -MACHINE* \ | -subsystem* | -SUBSYSTEM* \ | -verbose | -VERBOSE \ | -wx* | -WX* ) AR="$AR $1" shift ;; *) action=$1 shift break ;; esac done orig_archive=$1 shift func_file_conv "$orig_archive" archive=$file # strip leading dash in $action action=${action#-} delete= extract= list= quick= replace= index= create= while test -n "$action" do case $action in d*) delete=yes ;; x*) extract=yes ;; t*) list=yes ;; q*) quick=yes ;; r*) replace=yes ;; s*) index=yes ;; S*) ;; # the index is always updated implicitly c*) create=yes ;; u*) ;; # TODO: don't ignore the update modifier v*) ;; # TODO: don't ignore the verbose modifier *) func_error "unknown action specified" ;; esac action=${action#?} done case $delete$extract$list$quick$replace,$index in yes,* | ,yes) ;; yesyes*) func_error "more than one action specified" ;; *) func_error "no action specified" ;; esac if test -n "$delete"; then if test ! -f "$orig_archive"; then func_error "archive not found" fi for member do case $1 in @*) func_at_file "${1#@}" -REMOVE "$archive" ;; *) func_file_conv "$1" $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $? ;; esac done elif test -n "$extract"; then if test ! -f "$orig_archive"; then func_error "archive not found" fi if test $# -gt 0; then for member do case $1 in @*) func_at_file "${1#@}" -EXTRACT "$archive" ;; *) func_file_conv "$1" $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $? ;; esac done else $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member do $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $? done fi elif test -n "$quick$replace"; then if test ! -f "$orig_archive"; then if test -z "$create"; then echo "$me: creating $orig_archive" fi orig_archive= else orig_archive=$archive fi for member do case $1 in @*) func_file_conv "${1#@}" set x "$@" "@$file" ;; *) func_file_conv "$1" set x "$@" "$file" ;; esac shift shift done if test -n "$orig_archive"; then $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $? else $AR -NOLOGO -OUT:"$archive" "$@" || exit $? fi elif test -n "$list"; then if test ! -f "$orig_archive"; then func_error "archive not found" fi $AR -NOLOGO -LIST "$archive" || exit $? fi ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ac-aux/config.sub������������������������������������������������������������������������0000755�0001750�0001750�00000105354�12605311445�012571� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2013-08-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see <http://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.sub ($timestamp) Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or1k-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ac-aux/install-sh������������������������������������������������������������������������0000755�0001750�0001750�00000033255�12605311445�012612� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ac-aux/ltmain.sh�������������������������������������������������������������������������0000644�0001750�0001750�00001052044�12605311443�012422� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to <bug-libtool@gnu.org>. # GNU libtool home page: <http://www.gnu.org/software/libtool/>. # General help using GNU software: <http://www.gnu.org/gethelp/>. PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1.7ubuntu1" TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T <<EOF # $write_libobj - a libtool object file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # Name of the PIC object. pic_object=$write_lobj # Name of the non-PIC object non_pic_object=$write_oldobj EOF $MV "${write_libobj}T" "${write_libobj}" } } ################################################## # FILE NAME AND PATH CONVERSION HELPER FUNCTIONS # ################################################## # func_convert_core_file_wine_to_w32 ARG # Helper function used by file name conversion functions when $build is *nix, # and $host is mingw, cygwin, or some other w32 environment. Relies on a # correctly configured wine environment available, with the winepath program # in $build's $PATH. # # ARG is the $build file name to be converted to w32 format. # Result is available in $func_convert_core_file_wine_to_w32_result, and will # be empty on error (or when ARG is empty) func_convert_core_file_wine_to_w32 () { $opt_debug func_convert_core_file_wine_to_w32_result="$1" if test -n "$1"; then # Unfortunately, winepath does not exit with a non-zero error code, so we # are forced to check the contents of stdout. On the other hand, if the # command is not found, the shell will set an exit code of 127 and print # *an error message* to stdout. So we must check for both error code of # zero AND non-empty stdout, which explains the odd construction: func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen <import library>. $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 </dev/null >/dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat <<EOF /* $cwrappersource - temporary wrapper executable for $objdir/$outputname Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION The $output program cannot be directly executed until all the libtool libraries that it depends on are installed. This wrapper executable should never be moved out of the build directory. If it is, it will not operate correctly. */ EOF cat <<"EOF" #ifdef _MSC_VER # define _CRT_SECURE_NO_DEPRECATE 1 #endif #include <stdio.h> #include <stdlib.h> #ifdef _MSC_VER # include <direct.h> # include <process.h> # include <io.h> #else # include <unistd.h> # include <stdint.h> # ifdef __CYGWIN__ # include <io.h> # endif #endif #include <malloc.h> #include <stdarg.h> #include <assert.h> #include <string.h> #include <ctype.h> #include <errno.h> #include <fcntl.h> #include <sys/stat.h> /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <<EOF volatile const char * MAGIC_EXE = "$magic_exe"; const char * LIB_PATH_VARNAME = "$shlibpath_var"; EOF if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then func_to_host_path "$temp_rpath" cat <<EOF const char * LIB_PATH_VALUE = "$func_to_host_path_result"; EOF else cat <<"EOF" const char * LIB_PATH_VALUE = ""; EOF fi if test -n "$dllsearchpath"; then func_to_host_path "$dllsearchpath:" cat <<EOF const char * EXE_PATH_VARNAME = "PATH"; const char * EXE_PATH_VALUE = "$func_to_host_path_result"; EOF else cat <<"EOF" const char * EXE_PATH_VARNAME = ""; const char * EXE_PATH_VALUE = ""; EOF fi if test "$fast_install" = yes; then cat <<EOF const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */ EOF else cat <<EOF const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */ EOF fi cat <<"EOF" #define LTWRAPPER_OPTION_PREFIX "--lt-" static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX; static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script"; static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug"; int main (int argc, char *argv[]) { char **newargz; int newargc; char *tmp_pathspec; char *actual_cwrapper_path; char *actual_cwrapper_name; char *target_name; char *lt_argv_zero; intptr_t rval = 127; int i; program_name = (char *) xstrdup (base_name (argv[0])); newargz = XMALLOC (char *, argc + 1); /* very simple arg parsing; don't want to rely on getopt * also, copy all non cwrapper options to newargz, except * argz[0], which is handled differently */ newargc=0; for (i = 1; i < argc; i++) { if (strcmp (argv[i], dumpscript_opt) == 0) { EOF case "$host" in *mingw* | *cygwin* ) # make stdout use "unix" line endings echo " setmode(1,_O_BINARY);" ;; esac cat <<"EOF" lt_dump_script (stdout); return 0; } if (strcmp (argv[i], debug_opt) == 0) { lt_debug = 1; continue; } if (strcmp (argv[i], ltwrapper_option_prefix) == 0) { /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX namespace, but it is not one of the ones we know about and have already dealt with, above (inluding dump-script), then report an error. Otherwise, targets might begin to believe they are allowed to use options in the LTWRAPPER_OPTION_PREFIX namespace. The first time any user complains about this, we'll need to make LTWRAPPER_OPTION_PREFIX a configure-time option or a configure.ac-settable value. */ lt_fatal (__FILE__, __LINE__, "unrecognized %s option: '%s'", ltwrapper_option_prefix, argv[i]); } /* otherwise ... */ newargz[++newargc] = xstrdup (argv[i]); } newargz[++newargc] = NULL; EOF cat <<EOF /* The GNU banner must be the first non-error debug message */ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n"); EOF cat <<"EOF" lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]); lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name); tmp_pathspec = find_executable (argv[0]); if (tmp_pathspec == NULL) lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]); lt_debugprintf (__FILE__, __LINE__, "(main) found exe (before symlink chase) at: %s\n", tmp_pathspec); actual_cwrapper_path = chase_symlinks (tmp_pathspec); lt_debugprintf (__FILE__, __LINE__, "(main) found exe (after symlink chase) at: %s\n", actual_cwrapper_path); XFREE (tmp_pathspec); actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path)); strendzap (actual_cwrapper_path, actual_cwrapper_name); /* wrapper name transforms */ strendzap (actual_cwrapper_name, ".exe"); tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1); XFREE (actual_cwrapper_name); actual_cwrapper_name = tmp_pathspec; tmp_pathspec = 0; /* target_name transforms -- use actual target program name; might have lt- prefix */ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME)); strendzap (target_name, ".exe"); tmp_pathspec = lt_extend_str (target_name, ".exe", 1); XFREE (target_name); target_name = tmp_pathspec; tmp_pathspec = 0; lt_debugprintf (__FILE__, __LINE__, "(main) libtool target name: %s\n", target_name); EOF cat <<EOF newargz[0] = XMALLOC (char, (strlen (actual_cwrapper_path) + strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1)); strcpy (newargz[0], actual_cwrapper_path); strcat (newargz[0], "$objdir"); strcat (newargz[0], "/"); EOF cat <<"EOF" /* stop here, and copy so we don't have to do this twice */ tmp_pathspec = xstrdup (newargz[0]); /* do NOT want the lt- prefix here, so use actual_cwrapper_name */ strcat (newargz[0], actual_cwrapper_name); /* DO want the lt- prefix here if it exists, so use target_name */ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1); XFREE (tmp_pathspec); tmp_pathspec = NULL; EOF case $host_os in mingw*) cat <<"EOF" { char* p; while ((p = strchr (newargz[0], '\\')) != NULL) { *p = '/'; } while ((p = strchr (lt_argv_zero, '\\')) != NULL) { *p = '/'; } } EOF ;; esac cat <<"EOF" XFREE (target_name); XFREE (actual_cwrapper_path); XFREE (actual_cwrapper_name); lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */ lt_setenv ("DUALCASE", "1"); /* for MSK sh */ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath) because on Windows, both *_VARNAMEs are PATH but uninstalled libraries must come first. */ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE); lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE); lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n", nonnull (lt_argv_zero)); for (i = 0; i < newargc; i++) { lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n", i, nonnull (newargz[i])); } EOF case $host_os in mingw*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ newargz = prepare_spawn (newargz); rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); if (rval == -1) { /* failed to start process */ lt_debugprintf (__FILE__, __LINE__, "(main) failed to launch target \"%s\": %s\n", lt_argv_zero, nonnull (strerror (errno))); return 127; } return rval; EOF ;; *) cat <<"EOF" execv (lt_argv_zero, newargz); return rval; /* =127, but avoids unused variable warning */ EOF ;; esac cat <<"EOF" } void * xmalloc (size_t num) { void *p = (void *) malloc (num); if (!p) lt_fatal (__FILE__, __LINE__, "memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL; } const char * base_name (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha ((unsigned char) name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return base; } int check_executable (const char *path) { struct stat st; lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if ((stat (path, &st) >= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c <<EOF int main() { return 0; } EOF $opt_dry_run || $RM conftest if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then ldd_output=`ldd conftest` for i in $deplibs; do case $i in -l*) func_stripname -l '' "$i" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $i "*) func_append newdeplibs " $i" i="" ;; esac fi if test -n "$i" ; then libname=`eval "\\$ECHO \"$libname_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` set dummy $deplib_matches; shift deplib_match=$1 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then func_append newdeplibs " $i" else droppeddeps=yes echo $ECHO "*** Warning: dynamic linker does not accept needed library $i." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which I believe you do not have" echo "*** because a test_compile did reveal that the linker did not use it for" echo "*** its dynamic dependency list that programs get resolved with at runtime." fi fi ;; *) func_append newdeplibs " $i" ;; esac done else # Error occurred in the first compile. Let's try to salvage # the situation: Compile a separate program for each library. for i in $deplibs; do case $i in -l*) func_stripname -l '' "$i" name=$func_stripname_result $opt_dry_run || $RM conftest if $LTCC $LTCFLAGS -o conftest conftest.c $i; then ldd_output=`ldd conftest` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $i "*) func_append newdeplibs " $i" i="" ;; esac fi if test -n "$i" ; then libname=`eval "\\$ECHO \"$libname_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` set dummy $deplib_matches; shift deplib_match=$1 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then func_append newdeplibs " $i" else droppeddeps=yes echo $ECHO "*** Warning: dynamic linker does not accept needed library $i." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because a test_compile did reveal that the linker did not use this one" echo "*** as a dynamic dependency that programs can get resolved with at runtime." fi fi else droppeddeps=yes echo $ECHO "*** Warning! Library $i is needed by this library but I was not able to" echo "*** make it link in! You will probably need to install it or some" echo "*** library that it depends on before this library will be fully" echo "*** functional. Installing it before continuing would be even better." fi ;; *) func_append newdeplibs " $i" ;; esac done fi ;; file_magic*) set dummy $deplibs_check_method; shift file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` if test -n "$file_magic_glob"; then libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` else libnameglob=$libname fi test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do if test "$want_nocaseglob" = yes; then shopt -s nocaseglob potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ac-aux/config.guess����������������������������������������������������������������������0000755�0001750�0001750�00000130361�12605311445�013122� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2013-06-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see <http://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include <features.h> #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include <stdio.h> /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include <sys/systemcfg.h> main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include <stdlib.h> #include <unistd.h> int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include <unistd.h> int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; or1k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` echo ${UNAME_MACHINE}-pc-isc$UNAME_REL elif /bin/uname -X 2>/dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says <Richard.M.Bartel@ccMail.Census.GOV> echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes <hewes@openmarket.com>. # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac eval $set_cc_for_build cat >$dummy.c <<EOF #ifdef _SEQUENT_ # include <sys/types.h> # include <sys/utsname.h> #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include <sys/param.h> printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include <sys/param.h> # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 <<EOF $0: unable to guess system type This script, last modified $timestamp, has failed to recognize the operating system you are using. It is advised that you download the most up to date version of the config scripts from http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD and http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD If the version you run ($0) is already up to date, please send the following data and any information you think might be pertinent to <config-patches@gnu.org> in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ac-aux/depcomp���������������������������������������������������������������������������0000755�0001750�0001750�00000056016�12605311446�012164� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to <bug-automake@gnu.org>. EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ac-aux/compile���������������������������������������������������������������������������0000755�0001750�0001750�00000016245�12605311445�012164� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey <tromey@cygnus.com>. # # 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 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to <bug-automake@gnu.org> or send patches to # <automake-patches@gnu.org>. nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to <bug-automake@gnu.org>. EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/����������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312016�012163� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12605312016�013124� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/Makefile.in������������������������������������������������������������0000664�0001750�0001750�00000051730�12605311445�015126� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/wiki DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ SUBDIRS = src ebin EXTRA_DIST = wiki.conf start.sh README www INSTDIR = $(DESTDIR)$(appsdir)/wiki all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/wiki/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/wiki/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local 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 installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-local install-data-local: $(AM_V_at)$(INSTALL) -d $(INSTDIR) $(AM_V_at)(cd @srcdir@; tar cf - www ) | (cd $(INSTDIR); tar xf - ) $(AM_V_at)chmod -R u+rw $(INSTDIR)/www uninstall-local: $(AM_V_at)rm -fr $(INSTDIR)/www # 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: ����������������������������������������yaws-2.0.2/applications/wiki/README�����������������������������������������������������������������0000664�0001750�0001750�00000004510�12605311412�013725� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This Wiki was originally based on Joe Armstrongs wiki implementation. It has been ported to yaws and hacked quite a bit in general by Johan Bevemyr. To Install ---------- - Yaws should be installed - Run 'make install' - Edit your /etc/yaws.conf and include $(vardir)/yaws/wiki/ebin in the ebin path: ebin_dir = $(vardir)/yaws/wiki/ebin It is possible to have several Wiki instances on the same server. Just install the www/* files in the directory where you want a Wiki instance. This is easily done by running the updateWiki script and give a new directory as argument. To edit the wiki preferences go to the wiki page WikiPreferences (for example by clicking on the "All Pages" or "Zombies" icon) and replace the gifs with our own favorites. The password to the WikiPreferences page is ForgetMe. Getting started --------------- WIKIINSTALLDIR is where the wiki is located. It must be part of your docroot. After installation, browse to the wiki directory. You will be asked to create a 'home' page, which will be the first wiki page. To find out about the special wiki formatting rules, go to WikiFormattingRules (e.g. from "All Pages"). To create a new page, just create a link to it by clicking EditMe on the home page (use the ~ character: "my new page ~TestPage"), and save the home page. The new link will show up as: "my new page TestPage???". The question marks means that the node TestPage doens't exist. Click on the question marks to create the the page. Look and feel ------------- The layout of the Wiki pages is to a large extent controlled by two templates in WikiPreferences.files called template.html and template_info.html. There is an alternative look and feel bundled, just copy template2.html to template.html and template_info2.html to template_info.html. To maintain ----------- There are a number of useful scripts in the script directory. updateWiki - takes a number of wiki directories and updates the .yaws files etc getPassword - takes a path to a wob file as argument. Will print the password associated with that node. importFiles - takes a path to a wob file as argument. Will add any files in the corresponding .files directory to the page. Useful when you want to import many files without going through the WEB GUI. Just copy the files to the .files directory and run the importFiles command. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/start.sh���������������������������������������������������������������0000775�0001750�0001750�00000000037�12605311412�014541� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh yaws -i -c wiki.conf �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/ebin/������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312016�014043� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/ebin/Makefile.in�������������������������������������������������������0000664�0001750�0001750�00000041271�12605311445�016042� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/wiki/ebin DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(beamdir)" DATA = $(beam_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ beamdir = $(appsdir)/wiki/ebin/ BEAM_FILES = *.beam beam_DATA = $(BEAM_FILES) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/wiki/ebin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/wiki/ebin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-beamDATA: $(beam_DATA) @$(NORMAL_INSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(beamdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(beamdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(beamdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(beamdir)" || exit $$?; \ done uninstall-beamDATA: @$(NORMAL_UNINSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(beamdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(beamdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-beamDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-beamDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-beamDATA install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-beamDATA clean-local: $(AM_V_at)rm -f $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: # 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: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/ebin/Makefile.am�������������������������������������������������������0000664�0001750�0001750�00000000253�12605311412�016016� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������beamdir = $(appsdir)/wiki/ebin/ BEAM_FILES = *.beam beam_DATA = $(BEAM_FILES) clean-local: $(AM_V_at)rm -f $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/wiki.conf��������������������������������������������������������������0000664�0001750�0001750�00000000211�12605311412�014651� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������logdir = logs ebin_dir = ebin include_dir = include <server localhost> port = 8000 listen = 127.0.0.1 docroot = wiki </server> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/src/�������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312016�013715� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/src/Makefile.in��������������������������������������������������������0000664�0001750�0001750�00000036362�12605311445�015721� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/wiki/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = utils.erl \ wiki_diff.erl \ wiki.erl \ wiki_format_txt.erl \ wiki_plugin_backlinks.erl \ wiki_plugin_dummy.erl \ wiki_plugin_menu.erl \ wiki_split.erl \ wiki_templates.erl \ wiki_to_html.erl \ wiki_utils.erl \ wiki_yaws.erl EXTRA_DIST = $(MODULES) EBIN_DIR = @builddir@/../ebin EBIN_FILES = $(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/wiki/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/wiki/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) clean-local: $(AM_V_at)rm -f $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/src/wiki_split.erl�����������������������������������������������������0000664�0001750�0001750�00000006733�12605311412�016527� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-module(wiki_split). %% File : wiki_format_txt.erl %% Author : Joe Armstrong (joe@bluetail.com) %% : Johan Bevemyr, minor modifications %% Purpose : Wiki formatting engine %% %% Split the text. Looking for blocks %% < is represented as {open,Tag,string()} %% ... %% > %% < is represented as {write_append,Tag,string()} %% ... %% > %% %% Everything else is represented as {txt, Tag, string()} %% +type str2wiki(string()) -> wikiText(). %% +type wiki2str(wikiText()) -> string(). %% +type getRegion(tag(), wikiText()) -> string(). %% +type putRegion(tag(), wikiText(), string()) -> wikiText(). %% +type writeAppendRegion(tag(), wikiText(), string()) -> wikiText(). %% +deftype wikiText() = {wik, [{text,tag(),string()} | %% {open,tag(),string()} | %% {write_append, tag(), string()}]} %% +deftype tag() = int(). -export([str2wiki/1, wiki2str/1, getRegion/2, putRegion/3, writeAppendRegion/3]). -import(lists, [reverse/1]). str2wiki(Str) -> Blocks = str2wiki(Str, []), {wik, number_blocks(Blocks, 1)}. number_blocks([{txt,[]}|T], N) -> number_blocks(T, N); number_blocks([{Tag,Str}|T], N) -> [{Tag,N,Str}|number_blocks(T, N+1)]; number_blocks([], _) -> []. str2wiki(Str, L) -> {Before, Stuff} = collect_str(Str), case Stuff of "<<\n" ++ T -> {In, Str3} = collect_write_append([$\n|T], []), str2wiki(Str3, [{write_append,In},{txt,Before}|L]); "<\n" ++ T -> {In, Str3} = collect_open_region([$\n|T], []), str2wiki(Str3, [{open,In},{txt,Before}|L]); [] -> reverse([{txt,Before}|L]) end. %% collect_str(Str) -> {Str1, Str2} %% where Str2 == [], "<" ++ _ | "<<" ++ _ collect_str(Str) -> collect_after_nl(Str, []). collect_after_nl(S = "<<\n" ++ _, L) -> {reverse(L), S}; collect_after_nl(S = "<\n" ++ _, L) -> {reverse(L), S}; collect_after_nl(X, L) -> collect_str(X, L). collect_str([$\n|T], L) -> collect_after_nl(T, [$\n|L]); collect_str([H|T], L) -> collect_str(T, [H|L]); collect_str([], L) -> {reverse(L), []}. collect_write_append("\n>>\n" ++ T, L) -> {reverse([$\n|L]), [$\n|T]}; collect_write_append([H|T], L) -> collect_write_append(T, [H|L]); collect_write_append([], L) -> {reverse(L), []}. collect_open_region("\n>\n" ++ T, L) -> {reverse([$\n|L]), [$\n|T]}; collect_open_region([H|T], L) -> collect_open_region(T, [H|L]); collect_open_region([], L) -> {reverse(L), []}. %% wiki2str. wiki2str({wik,L}) -> sneaky_flatten(wiki2str1(L)). wiki2str1([{txt,_,Str}|T]) -> [Str|wiki2str1(T)]; wiki2str1([{open,_,Str}|T]) -> ["<\n",Str,"\n>"|wiki2str1(T)]; wiki2str1([{write_append,_,Str}|T]) -> ["<<\n",Str,"\n>>"|wiki2str1(T)]; wiki2str1([]) -> []. sneaky_flatten(L) -> binary_to_list(list_to_binary(L)). getRegion(Tag, {wik, L}) -> getRegion1(Tag, L). getRegion1(Tag, [{Type,Tag,Str}|_]) -> {Type, Str}; getRegion1(Tag, [_|T]) -> getRegion1(Tag, T). putRegion(Tag, {wik, L}, Str1) -> {wik, putRegion1(Tag, L, Str1)}. putRegion1(Tag, [{Type,Tag,_}|T], New) -> [{Type,Tag,New}|T]; putRegion1(Tag, [H|T], New) -> [H|putRegion1(Tag, T, New)]. writeAppendRegion(Tag, Wik, Str) -> Str1 = getRegion(Tag, Wik), putRegion(Tag, Wik, Str ++ Str1). �������������������������������������yaws-2.0.2/applications/wiki/src/wiki_to_html.erl���������������������������������������������������0000664�0001750�0001750�00000010347�12605311412�017036� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-module(wiki_to_html). %% File : wiki_to_html.erl %% Author : Joe Armstrong (joe@bluetail.com) %% : Johan Bevemyr, minor modifications (jb@bevemyr.com) %% : Mickael Remond (mickael.remond@erlang-fr.org) %% Purpose : Convert wiki page tree to HTML %% %% $Id$ -export([format_wiki/3,format_wiki/4, format_link/2, format_wiki_files/4, format_wiki_files/5, format_menu_link/3]). -include_lib("kernel/include/file.hrl"). -import(lists, [member/2, map/2]). format_wiki_files(_Page, _FileDir, [], _Root) -> []; format_wiki_files(Page, FileDir, Files, Root) -> format_wiki_files(Page, FileDir, Files, Root, "Attached files:"). format_wiki_files(Page, FileDir, Files, Root, Heading) -> LinkFun = fun(I) -> format_link(I, FileDir, Page, Root, show) end, ("<hr><b><p>" ++ yaws_api:htmlize(Heading) ++ "</b><br>\n" "<table cellspacing=10 width = \"100%\">\n" ++ lists:map(LinkFun, lists:keysort(2,Files)) ++ "</table></p>\n"). format_wiki(Page, Wik, Root) -> LinkFun = fun(I) -> format_link(I, Page, Root, show) end, pp(Wik, LinkFun, Page, Root). format_wiki(Page, Wik, Root, preview) -> LinkFun = fun(I) -> format_link(I, Page, Root, preview) end, pp(Wik, LinkFun, Page, Root). format_link(Page, Root) -> format_link({wikiLink, Page}, [], Root, show). %% TODO: Refactor that: The use of the page is ugly: %% Most of the time the Page is in the second parameter, %% but in the wikiLink it is the second element of the first parameter tuple format_link({wikiLink, Page}, _, Root, _Mode) -> %% MR: I first need to extract the code here into a separate function: wiki_link(Page, Page, Root); format_link({editTag, Tag}, Page, _Root, show) -> ["<a href=\"editTag.yaws?node=",wiki:str2urlencoded(Page), "&tag=",i2s(Tag),"\">", "<img border=0 src='WikiPreferences.files/edit.gif'></a> "]; format_link({editTag, _Tag}, _Page, _Root, preview) -> ["<img border=0 src='WikiPreferences.files/edit.gif'>"]. format_link({file, FileName, C}, FileDir, Page, Root, Mode) -> format_link({file, FileName, "", C}, FileDir, Page, Root, Mode); format_link({file, FileName, Description, _}, FileDir, _Page, Root,_) -> Size = get_filesize(filename:join([Root,FileDir,FileName])), ["<tr><td valign=top align=left><a href=\"", wiki:str2urlencoded(FileDir), "/", wiki:str2urlencoded(FileName),"\" title='",Size,"'>", yaws_api:htmlize(FileName), "</a></td><td align=left valign=top>", yaws_api:htmlize(Description), "</td></tr>\n"]. wiki_link(LinkName, Page, Root) -> FullName = Root ++ "/" ++ Page ++ ".wob", case is_file(FullName) of true -> ["<a href=\"showPage.yaws?node=", wiki:str2urlencoded(Page),"\">",yaws_api:htmlize(LinkName),"</a> "]; false -> [" ",yaws_api:htmlize(Page),"<a href=\"createNewPage.yaws?node=", wiki:str2urlencoded(Page),"\">???</a>"] end. %% Same as format_link, but drop the prefix %% This is used to create the Wiki menu format_menu_link(Prefix, Page, Root) -> Prefix_length = length(Prefix), LinkName = case Prefix_length < length(Page) of true -> string:substr(Page, Prefix_length + 1); false -> Page end, wiki_link(LinkName, Page, Root). get_filesize(File) -> case file:read_file_info(File) of {ok, FileInfo} -> Size = FileInfo#file_info.size/1024, io_lib:format("~.1fKB",[Size]); _ -> "unknown" end. i2s(X) -> integer_to_list(X). pp({wik,L}, F, Node, Root) -> map(fun(I) -> pp(I, F, Node, Root) end, L); pp({txt,_,Str}, F, Node, _Root) -> wiki_format_txt:format(Str, F, Node); pp({open,Tag,Str}, F, Node, Root) -> open("#CCFFCC",Tag,F,pp({txt,9999,Str}, F, Node, Root)); pp({write_append,Tag,Str}, F, Node, Root) -> open("#99FFFF",Tag,F,pp({txt,8888,Str}, F, Node, Root)); pp(Other, _F, _Node, Root) -> wiki:show({cannot,format,Other}, Root). open(Color, Tag, F, Stuff) -> ["\n<table width=\"90%\" cellpadding=20>\n<tr><td bgcolor=\"", Color, "\">\n", Stuff, "<p>",F({editTag,Tag}),"</td></tr></table><p>\n"]. is_file(File) -> case file:read_file_info(File) of {ok, _} -> true; _ -> false end. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/src/utils.erl����������������������������������������������������������0000664�0001750�0001750�00000004646�12605311412�015512� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-module(utils). %%% File : utils.erl %%% Author : Mickael Remond <mickael.remond@erlang-fr.org> %%% Description : Various general purpose helper functions %%% Created : 22 Oct 2003 by Mickael Remond %%% <mickael.remond@erlang-fr.org> -export([time_to_string/1]). -export([fold_files/3, fold_files/5]). %% Time (as return by calendar:local_time() to string conversion. time_to_string( {{Y,Mo,D},{H,Mi,S}} ) -> String = io_lib:format( "~4.4w-~2.2.0w-~2.2.0w ~2.2.0w:~2.2.0w:~2.2.0w", [Y,Mo,D,H,Mi,S] ), lists:flatten(String). %% Fold_files is a rewrite by Chris Pressey of the broken %% implementation in Erlang R9C %% @spec fold_files(dir(), fun(), term()) -> term() %% @doc Folds the function Fun(F, IsDir, Acc) -> {Recurse, Acc1} over %% all files F in Dir that match the regular expression RegExp. %% If Recurse is true all sub-directories of F are processed. %% (This function is a modified version of that from filelib.erl) fold_files(Dir, Fun, Acc) -> case file:list_dir(Dir) of {ok, Files} -> fold_files0(Files, Dir, Fun, Acc); {error, _} -> Acc end. fold_files0([File | Tail], Dir, Fun, Acc) -> FullName = filename:join([Dir, File]), IsDir = filelib:is_dir(FullName), {Recurse, NewAcc} = Fun(FullName, IsDir, Acc), fold_files0(FullName, Tail, Dir, Fun, IsDir, Recurse, NewAcc); fold_files0([], _Dir, _Fun, Acc) -> Acc. fold_files0(FullName, Tail, Dir, Fun, true, true, Acc) -> NewAcc = fold_files(FullName, Fun, Acc), fold_files0(Tail, Dir, Fun, NewAcc); fold_files0(_FullName, Tail, Dir, Fun, _, _, Acc) -> fold_files0(Tail, Dir, Fun, Acc). %% @spec fold_files(dir(), regexp(), bool(), fun(), term()) -> term() %% Wrapper for the original fold_files/5 behaviour. fold_files(Dir, RegExp, Recursive, Fun, InitialAcc) -> {ok, CompiledRegExp} = re:compile(RegExp), Wrapper = fun (FullName, false, Acc) -> NewAcc = case re:run(FullName, CompiledRegExp) of {match, _} -> Fun(FullName, Acc); _ -> Acc end, {Recursive, NewAcc}; (_, true, Acc) -> {Recursive, Acc} end, fold_files(Dir, Wrapper, InitialAcc). ������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/src/wiki.erl�����������������������������������������������������������0000664�0001750�0001750�00000252757�12605311412�015325� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������% -*- coding: utf-8 -*- % File: wiki.erl (~jb/work/wiki/src/wiki.erl) % Author: Joe Armstrong % Author: Johan Bevemyr % Purpose: Wiki web in Erlang %% %% History: Ported and partly rewritten by Johan Bevemyr for %% the yaws http server. %% %% History: First started by Luke Gorrie who wrote the first %% Erlang wiki. Subsequently re-written many times by Joe Armstrong %% and Luke Gorrie. %% This version by Joe Armstrong. %% Thanks to Luke and Robert Virding for many helpfull %% discussions clarifying the design. %% This also makes use of the new pico_http_server which has %% a much simplified interface. -module('wiki'). -author('jb@son.bevemyr.com'). -compile(export_all). -export([showPage/3, createNewPage/3, showHistory/3, allPages/3, lastEdited/3, wikiZombies/3, editPage/3, editFiles/3, previewNewPage/3, allRefsToMe/3, deletePage/3, editTag/3, finalDeletePage/3, storePage/3, putPassword/3, storeNewPage/3, previewPage/3, previewTagged/3, copyFiles/3, deleteFiles/3, addFile/1, addFile/2, addFile/3, storeTagged/3, fixupFiles/3, sendMeThePassword/3, storeFiles/3, showOldPage/3, changePassword/3, changePassword2/3, getThumb/3, getMidSize/3, thumbIndex/3, searchPages/3]). -export([slideShow/3]). -export([show/2, ls/1, h1/1, read_page/2, p/1, str2urlencoded/1, session_manager_init/2]). -export([getPassword/1]). -export([importFiles/1]). -import(lists, [reverse/1, map/2, sort/1]). -import(wiki_templates, [template/5, template2/5]). -include("../../../include/yaws_api.hrl"). -include_lib("kernel/include/file.hrl"). % This should be -include:ed instead showPage(Params, Root, Prefix) -> Page = getnode(Params), if Page == undefined -> html_error(invalid_request); true -> {WobFile, FileDir} = page2filename(Page, Root), case file:read_file(WobFile) of {ok, Bin} -> {wik002, Pwd,_Email,Time,_Who,TxtStr,Files,_Patches} = bin_to_wik002(Root,FileDir,Bin), Wik = wiki_split:str2wiki(TxtStr), DeepStr = wiki_to_html:format_wiki(Page, Wik, Root), DeepFiles = wiki_to_html:format_wiki_files( Page, FileDir, Files, Root), Locked = Pwd /= "", wiki_templates:template(Page, Root, [DeepStr, DeepFiles], utils:time_to_string(Time), Locked); _ -> NewSid = session_new(initial_page_content()), redirect_create(Page, NewSid, Prefix) end end. thumb_name(File) -> Extension = filename:extension(File), (filename:basename(File, Extension)++"_wiki_thb"++Extension). create_thumb_if_needed(SrcPath, DstPath) -> case thumb_up2date(SrcPath, DstPath) of true -> ok; false -> create_thumb(SrcPath, DstPath) end. thumb_up2date(Src,Thumb) -> DstAge = get_age(Thumb), SrcAge = get_age(Src), DstAge > SrcAge. create_thumb(SrcPath, DstPath) -> os:cmd("convert -size 90x90 -scale 90x90 '"++ shell_quote(SrcPath)++"' '"++ shell_quote(DstPath)++"'"). getThumb(Params, Root, Prefix) -> Page = getnode(Params), Pict = getopt("pict", Params), if Page == undefined -> html_error(invalid_request); true -> {_WobFile, FileDir} = page2filename(Page, Root), ThumbName = thumb_name(Pict), SrcPath = Root ++ "/" ++ FileDir ++ "/" ++ Pict, DstPath = Root ++ "/" ++ FileDir ++ "/" ++ ThumbName, UpToDate = thumb_up2date(SrcPath, DstPath), if UpToDate -> done; true -> create_thumb(SrcPath, DstPath) end, {redirect_local, Prefix++FileDir++"/"++ThumbName} end. getMidSize(Params, Root, Prefix) -> Page = getnode(Params), Pict = getopt("pict", Params), if Page == undefined -> html_error(invalid_request); true -> {_WobFile, FileDir} = page2filename(Page, Root), Extension = filename:extension(Pict), MidName = (filename:basename(Pict, Extension)++ "_wiki_mid"++Extension), SrcPath = Root ++ "/" ++ FileDir ++ "/" ++ Pict, DstPath = Root ++ "/" ++ FileDir ++ "/" ++ MidName, DstAge = get_age(DstPath), SrcAge = get_age(SrcPath), if DstAge > SrcAge -> false; true -> os:cmd("convert -size 400x400 -scale 400x400 '"++ shell_quote(SrcPath)++"' '"++ shell_quote(DstPath)++"'") end, case file:read_file_info(DstPath) of {error,_} -> {redirect_local, Prefix++FileDir++"/"++Pict}; _ -> {redirect_local, Prefix++FileDir++"/"++MidName} end end. shell_quote([]) -> []; shell_quote([$'|R]) -> [$\\, $'| shell_quote(R)]; shell_quote([C|R]) -> [C|shell_quote(R)]. get_age(Path) -> case file:read_file_info(Path) of {error, _} -> {{0,0,0},{0,0,0}}; {ok, FileInfo} -> FileInfo#file_info.mtime end. fixupFiles(Params, Root, Prefix) -> Page = getnode(Params), if Page == undefined -> html_error(invalid_request); true -> importFiles(Page, Root, Prefix) end. importFiles(Page, Root, Prefix) -> {WobFile, FileDir} = page2filename(Page, Root), case file:read_file(WobFile) of {ok, Bin} -> {wik002, Pwd,Email,Time,Who,TxtStr,Files,Patches} = bin_to_wik002(Root,FileDir,Bin), CurFiles = files(Root++"/"++FileDir, "^"), CurFileNames = [basename(CF) || CF <- CurFiles, string:str(CF,"_wiki_thb")==0, string:str(CF,"_wiki_mid")==0], F = fun(Fn) -> case lists:keysearch(Fn,2,Files) of {value, File} -> File; false -> {file, Fn, "", []} end end, NewFiles = [F(X) || X <- CurFileNames], Ds = {wik002, Pwd,Email,Time,Who,TxtStr,NewFiles,Patches}, B = term_to_binary(Ds), file:write_file(WobFile, B), redirect({node, Page}, Prefix); _ -> NewSid = session_new(initial_page_content()), redirect_create(Page, NewSid, Prefix) end. importFiles([WobFile]) -> FileDir = wobfile_to_filedir(WobFile), case file:read_file(WobFile) of {ok, Bin} -> {wik002, Pwd, Email, Time, Who, TxtStr, Files, Patches} = bin_to_wik002(Bin), CurFiles = files(FileDir, "^"), CurFileNames = [basename(CF) || CF <- CurFiles], F = fun(Fn) -> case lists:keysearch(Fn, 2, Files) of {value, File} -> File; false -> {file, Fn, "", []} end end, AddedFiles = [tostring(Y)++" " || Y <- CurFileNames, not(lists:keymember(Y,2,Files))], NewFiles = [F(X) || X <- CurFileNames], Ds = {wik002, Pwd,Email,Time,Who,TxtStr,NewFiles,Patches}, B = term_to_binary(Ds), BackupFile = tostring(WobFile)++".bak", file:write_file(BackupFile, Bin), io:format("Saved old wob file as ~s\n", [BackupFile]), file:write_file(WobFile, B), io:format("Added files: ~s\n", [AddedFiles]), halt(); _ -> io:format("Error - failed to read wob file"), halt() end. addFile([WobFile, FileAtm]) -> addFile([WobFile, FileAtm], halt). addFile([WobFile, FileAtm], Halt) -> _FileDir = wobfile_to_filedir(WobFile), File = tostring(FileAtm), case file:read_file(WobFile) of {ok, Bin} -> {wik002, Pwd, Email, Time, Who, TxtStr, Files, Patches} = bin_to_wik002(Bin), NewFiles = case lists:keysearch(File, 2, Files) of {value, _} -> Files; false -> [{file, File, "", []}|Files] end, Ds = {wik002, Pwd,Email,Time,Who,TxtStr,NewFiles,Patches}, B = term_to_binary(Ds), BackupFile = tostring(WobFile)++".bak", file:write_file(BackupFile, Bin), io:format("Saved old wob file as ~s\n", [BackupFile]), file:write_file(WobFile, B), io:format("Added file: ~s\n", [File]); _ -> io:format("Error - failed to read wob file") end, if Halt == halt -> halt(); true -> ok end. createNewPage(Params, Root, Prefix) -> Page = getnode(Params), Sid = getopt("sid", Params), if Sid /= undefined -> {Txt,Passwd,Email} = session_get_all(Sid, initial_page_content(), "", ""), createNewPage1(Page, Root, Sid, Prefix, Txt, Passwd, Email); Sid == undefined -> NewSid = session_new(initial_page_content()), redirect_create(Page, NewSid, Prefix) end. createNewPage1(Page, Root, Sid, _Prefix, Content, Passwd, Email) -> wiki_templates:template2( Root, "New Page", yaws_api:htmlize(Page), [p("Creating a new page. " "If you want a password protected page " "then fill in both the password fields - otherwise " "leave them blank."), p("If you fill in the email field and forget the page password " "then the system can mail you back the password of the page if " "you forget it."), p("Click on 'Preview' when you are ready to store the page."), form("POST", "previewNewPage.yaws?sid="++str2urlencoded(Sid), [input("submit", "review", "Preview"), input("hidden", "node", Page), hr(), "<table>\n" "<tr> <td align=left>Password: </td>", "<td align=left> ", password_entry("password1", 8, Passwd), "</td></tr>\n", "<tr> <td align=left>Reconfirm password: </td>", "<td align=left> ",password_entry("password2", 8, Passwd), "</td></tr>\n", "<tr> <td align=left>Email: </td>", "<td align=left> ", input("text","email",Email), "</td></tr>\n", "</table>\n", p(), textarea("text", 25, 72, Content), hr() ])], false). storePage(Params, Root, Prefix) -> Password = getopt("password", Params, ""), Page = getnode(Params), Cancel = getopt("cancel", Params), Edit = getopt("edit", Params), Sid = getopt("sid", Params), if Cancel /= undefined -> session_end(Sid), redirect({node, Page}, Prefix); true -> case checkPassword(Page, Password, Root, Prefix) of true -> if Edit /= undefined -> Txt0 = getopt("txt", Params), Txt = zap_cr(urlencoded2str(Txt0)), session_set_text(Sid, Txt), redirect_edit(Page, Sid, Password, Prefix); true -> storePage1(Params, Root, Prefix) end; false -> show({bad_password, Page}, Root); error -> show({no_such_page,Page}, Root) end end. storePage1(Params, Root, Prefix) -> Page = getnode(Params), Txt0 = getopt("txt", Params), Sid = getopt("sid", Params), Txt = zap_cr(urlencoded2str(Txt0)), session_end(Sid), {File,_FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> Wik = {wik002,_Pwd,_Email,_Time,_Who,_OldTxt,_Files,_Patches} = bin_to_wik002(Bin), store_ok(Page, Root, Prefix, Txt, Wik); _ -> show({no_such_page,Page}, Root) end. storeNewPage(Params, Root, Prefix) -> Page = getnode(Params), Password = getopt("password", Params), Email0 = getopt("email", Params), Txt0 = getopt("txt", Params), Txt = zap_cr(urlencoded2str(Txt0)), Email = urlencoded2str(Email0), %% Check the password {File,_FileDir} = page2filename(Page, Root), Time = {date(),time()}, Who = "unknown", B = term_to_binary({wik002,Password,Email,Time,Who,Txt,[],[]}), case file:write_file(File, B) of ok ->redirect({node, Page}, Prefix); {error, Reason} -> show({failed_to_create_page,file:format_error(Reason)}, Root) end. storeTagged(Params, Root, Prefix) -> Page = getnode(Params), Tag = getopt("tag", Params), Txt0 = getopt("txt", Params), case catch list_to_integer(Tag) of {'EXIT', _Reason} -> show({no_such_tag, Tag}, Root); ITag when is_integer(ITag) -> Txt = zap_cr(urlencoded2str(Txt0)), {File,_FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> Wik = {wik002,_Pwd,_Email,_Time,_Who,OldTxt,_Files,_Patches} = bin_to_wik002(Bin), W = wiki_split:str2wiki(OldTxt), {Type, Old} = wiki_split:getRegion(ITag, W), W2 = case Type of open -> wiki_split:putRegion(ITag, W, Txt); write_append -> Time = format_time({date(), time()}), wiki_split:putRegion(ITag, W, "''" ++ Time ++ "''\n\n" ++ Txt ++ "\n\n____\n" ++ Old) end, Str2 = wiki_split:wiki2str(W2), store_ok(Page, Root, Prefix, Str2, Wik); _ -> show({no_such_page,Page}, Root) end end. storeFiles(Params, Root, Prefix) -> Page = getnode(Params), Password = getopt("password", Params), Add = getopt("add", Params), Update = getopt("update", Params), Delete = getopt("delete", Params), Copy = getopt("copy", Params), Cancel = getopt("cancel", Params), case checkPassword(Page, Password, Root, Prefix) of true -> if Add /= undefined -> addFileInit(Params, Root, Prefix); Update /= undefined -> updateFilesInit(Params, Root, Prefix); Delete /= undefined -> deleteFilesInit(Params, Root, Prefix); Copy /= undefined -> copyFilesInit(Params, Root, Prefix); Cancel /= undefined -> redirect({node, Page}, Prefix); true -> show({no_such_page, Page}, Root) end; false -> getPassword(Page, Root, Prefix, storeFiles, Params); error -> show({no_such_page,Page}, Root) end. addFileInit(Params, Root, _Prefix) -> Page = getnode(Params), Password = getopt("password", Params), template2(Root, "Add File", Page, [form("POST", "addFile.yaws", [ input("hidden", "node", Page), input("hidden", "password", Password), "<table width=\"100%\">", "<tr><th align=left>Attach new file: </th>", "<th align=left>", input("file","attached","30"),"</th></tr>", "<tr><td colspan=2 align=left>", input("checkbox","unzip","on",""), "Upload multiple files using zip archive</th></tr>" "<tr><th colspan=2 align=left>", "Description: ","</th></tr>", "<tr><td colspan=2 align=left>", textarea("text", 10, 72,""),"</td></tr>", "</table>", input("submit", "add", "Add"), input("button", "Cancel", "parent.location='editFiles.yaws?node="++ str2urlencoded(Page)++"&password="++ str2urlencoded(Password)++"'")]), "To upload multiple files at one time place them in a zip archive and upload " "the zip file and check the 'unzip' checkbox above." ], false). -record(addfile, { root, prefix, param, password, node, text, cancel, fd, last, filename, unzip }). %%% addFile %%% More than a bit messy due to the chunked arguments :-( addFile(Arg, Root, Prefix) -> State = prepare_addFile_state(Arg#arg.state, Root, Prefix), case yaws_api:parse_multipart_post(Arg) of {cont, Cont, Res} -> case addFileChunk(Res, State) of {done, Result} -> Result; {cont, NewState} -> {get_more, Cont, NewState} end; {result, Res} -> case addFileChunk(Res, State#addfile{last=true}) of {done, Result} -> Result; {cont, _} -> show({error_on_upload, State#addfile.node}, Root) end end. prepare_addFile_state(undefined, Root, Prefix) -> #addfile{root=Root, prefix=Prefix}; prepare_addFile_state(State, Root, Prefix) -> State#addfile{root=Root, prefix=Prefix}. merge_body(undefined, Data) -> Data; merge_body(Acc, New) -> Acc ++ New. addFileChunk([{part_body, Data}|Res], State) -> addFileChunk([{body, Data}|Res], State); addFileChunk([], State) when State#addfile.last==true, State#addfile.filename /= undefined, State#addfile.unzip == "on", State#addfile.fd /= undefined -> file:close(State#addfile.fd), Page = State#addfile.node, {_File,FileDir} = page2filename(Page, State#addfile.root), FileName = State#addfile.filename, case lists:reverse(FileName) of "piz."++_ -> UnZipCmd = "cd '"++State#addfile.root++"/"++FileDir++ "'; unzip -j -o -qq '" ++ FileName ++"'; rm -f '" ++ FileName ++ "'", os:cmd(UnZipCmd); _ -> done end, {done, {redirect_local, {rel_path, "importFiles.yaws?node="++str2urlencoded(Page)}}}; addFileChunk([], State) when State#addfile.last==true, State#addfile.filename /= undefined, State#addfile.fd /= undefined -> Page = State#addfile.node, {File,_FileDir} = page2filename(Page, State#addfile.root), {ok, Bin} = file:read_file(File), {wik002,Pwd,Email,_,_,Txt,OldFiles,Patches} = bin_to_wik002(Bin), Description = State#addfile.text, FileName = State#addfile.filename, NewFile = {file, FileName, Description, []}, KeptOld = lists:keydelete(FileName, 2, OldFiles), NewFiles = [NewFile|KeptOld], Time = {date(), time()}, Who = "unknown", Ds = {wik002,Pwd, Email,Time,Who,Txt,NewFiles,Patches}, B = term_to_binary(Ds), file:write_file(File, B), file:close(State#addfile.fd), {done, redirect_files(Page, Pwd, State#addfile.prefix)}; % {done, redirect({node, Page}, State#addfile.prefix)}; addFileChunk([], State) when State#addfile.last==true -> Page = State#addfile.node, {done, show({error_in_upload, Page}, State#addfile.root)}; addFileChunk([], State) -> {cont, State}; addFileChunk([{head, {"add", _Opts}}|Res], State ) -> addFileChunk(Res, State#addfile{param = add}); addFileChunk([{body, _Data}|Res], State) when State#addfile.param == add -> addFileChunk(Res, State); addFileChunk([{head, {"node", _Opts}}|Res], State ) -> addFileChunk(Res, State#addfile{param = node}); addFileChunk([{body, Data}|Res], State) when State#addfile.param == node -> Node = State#addfile.node, NewNode = merge_body(Node, Data), addFileChunk(Res, State#addfile{node = NewNode}); addFileChunk([{head, {"unzip", _Opts}}|Res], State ) -> addFileChunk(Res, State#addfile{param = unzip}); addFileChunk([{body, Data}|Res], State) when State#addfile.param == unzip -> Unzip = State#addfile.unzip, NewUnzip = merge_body(Unzip, Data), addFileChunk(Res, State#addfile{unzip = NewUnzip}); addFileChunk([{head, {"password", _Opts}}|Res], State) -> addFileChunk(Res, State#addfile{param = password}); addFileChunk([{body, Data}|Res], State) when State#addfile.param == password -> Password = State#addfile.password, NewPW = merge_body(Password, Data), addFileChunk(Res, State#addfile{password = NewPW}); addFileChunk([{head, {"cancel", _Opts}}|_Res], State) -> {done, redirect({node, State#addfile.node}, State#addfile.prefix)}; addFileChunk([{head, {"text", _Opts}}|Res], State) -> addFileChunk(Res, State#addfile{param = text}); addFileChunk([{body, Data}|Res], State) when State#addfile.param == text -> Text = State#addfile.text, NewText = merge_body(Text, Data), addFileChunk(Res, State#addfile{text = NewText}); addFileChunk([{head, {"attached", Opts}}|Res], State) -> Page = State#addfile.node, Password = State#addfile.password, FilePath = getopt(filename, Opts), FileName = basename(FilePath), Root = State#addfile.root, Prefix = State#addfile.prefix, {_,FileDir} = page2filename(Page, Root), Valid = check_filename(lists:reverse(FileName)), if Valid /= ok -> {error, Reason} = Valid, {done, show({illegal_filename, FileName, Reason}, Root)}; FileName == "" -> {done, show({empty_content, Page}, Root)}; true -> case checkPassword(Page, Password, Root, Prefix) of true -> {ok, Fd} = file:open(Root++"/"++FileDir++"/"++ FileName, write), addFileChunk(Res, State#addfile{fd=Fd,param=attached, filename=FileName}); false -> {done, show({bad_password, Page}, Root)}; error-> {done, show({no_such_page,Page}, Root)} end end; addFileChunk([{body, Data}|Res], State) when State#addfile.param == attached -> file:write(State#addfile.fd, Data), addFileChunk(Res, State). check_filename("sway."++_) -> {error, "Files ending with .yaws files are not allowed."}; check_filename(FileName) -> case lists:any(fun(C) -> lists:member(C, FileName) end, "$\\!%^&*[]~\"'`<>|/") of true -> {error, "Illegal character in file. " "Please remove all of the following characters " "$\\!%^&*[]~\"'`<>|/ from the filename."}; false -> ok end. updateFilesInit(Params, Root, Prefix) -> Page = getnode(Params), Descriptions = [{lists:nthtail(4,N),S} || {N,S,_} <- Params, lists:prefix("cbt_",N)], {File,_FileDir} = page2filename(Page, Root), {ok, Bin} = file:read_file(File), Wik = bin_to_wik002(Bin), {wik002,Pwd,Email,_Time, _Who,Txt,OldFiles,Patches} = Wik, %% Update description field of file entry UpdateDesc = fun({file, Fname, OldDesc, []}) -> case lists:keysearch(Fname, 1, Descriptions) of {value, {_,NewDesc}} -> {file, Fname, NewDesc, []}; _ -> {file, Fname, OldDesc, []} end; ({file, Fname, _}) -> case lists:keysearch(Fname, 1, Descriptions) of {value, {_,NewDesc}} -> {file, Fname, NewDesc, []}; _ -> {file, Fname, [], []} end end, NewFiles = [UpdateDesc(F) || F <- OldFiles], Time = {date(), time()}, Who = "unknown", Ds = {wik002,Pwd, Email,Time,Who,Txt,NewFiles,Patches}, B = term_to_binary(Ds), file:write_file(File, B), redirect_files(Page, Pwd, Prefix). deleteFilesInit(Params, Root, _Prefix) -> Page = getnode(Params), Password = getopt("password", Params), CheckedFiles = [lists:nthtail(3,N) || {N,_,_} <- Params, lists:prefix("cb_",N)], {File,FileDir} = page2filename(Page, Root), {ok, Bin} = file:read_file(File), _Wik = {wik002,_Pwd,_Email,_Time, _Who,_Txt,Files,_Patches} = bin_to_wik002(Bin), Extend = fun({file, Name, Desc, _}) -> {file, Name, Desc, []}; ({file, Name, _}) -> {file, Name, "", []} end, OldFiles = [ Extend(F) || F <- Files], DelFiles = [ {file, Name, Desc, []} || {file, Name, Desc, _} <- OldFiles, lists:member(Name, CheckedFiles)], List = wiki_to_html:format_wiki_files(Page, FileDir, lists:keysort(2,DelFiles), Root, "The following files will be deleted " "from " ++ Page ++ "."), DelList = [input("hidden", "del_"++Name, Name) || {file, Name, _, _} <- DelFiles], template2(Root, "Confirm", Page, [List, form("POST", "deleteFiles.yaws", [DelList, input("submit", "delete", "Delete"), input("submit", "cancel", "Cancel"), input("hidden", "node", Page), input("hidden", "password", Password)]) ], false). deleteFiles(Params, Root, Prefix) -> Password = getopt("password", Params, ""), Page = getnode(Params), Cancel = getopt("cancel", Params), if Cancel /= undefined -> redirect({node, Page}, Prefix); true -> case checkPassword(Page, Password, Root, Prefix) of true -> deleteFiles1(Params, Root, Prefix); false -> show({bad_password, Page}, Root); error -> show({no_such_page,Page}, Root) end end. deleteFiles1(Params, Root, Prefix) -> Page = getnode(Params), CheckedFiles = [lists:nthtail(4,N) || {N,_,_} <- Params, lists:prefix("del_",N)], {File,FileDir} = page2filename(Page, Root), {ok, Bin} = file:read_file(File), _Wik = {wik002,Pwd,Email,_Time, _Who,Txt,Files,Patches} = bin_to_wik002(Bin), Extend = fun({file, Name, Desc, _}) -> {file, Name, Desc, []}; ({file, Name, _}) -> {file, Name, "", []} end, OldFiles = [ Extend(F) || F <- Files], DelFiles = [ {file, Name, Desc, []} || {file, Name, Desc, _} <- OldFiles, lists:member(Name, CheckedFiles)], NewFiles = [ {file, Name, Desc, []} || {file, Name, Desc, _} <- OldFiles, not lists:member(Name, CheckedFiles)], Time = {date(), time()}, Who = "unknown", Ds = {wik002,Pwd, Email,Time,Who,Txt,NewFiles,Patches}, B = term_to_binary(Ds), lists:foreach(fun({file,F,_,_}) -> Extension = filename:extension(F), BaseName = filename:basename(F, Extension), ThumbName = (BaseName++"_wiki_thb"++Extension), MidName = (BaseName++"_wiki_mid"++Extension), file:delete(Root++"/"++FileDir++"/"++ThumbName), file:delete(Root++"/"++FileDir++"/"++MidName), file:delete(Root++"/"++FileDir++"/"++F) end, DelFiles), file:write_file(File, B), redirect_files(Page, Pwd, Prefix). copyFilesInit(Params, Root, Prefix) -> Page = getnode(Params), Password = getopt("password", Params), CheckedFiles = [lists:nthtail(3,N) || {N,_,_} <- Params, lists:prefix("cb_",N)], {File,FileDir} = page2filename(Page, Root), {ok, Bin} = file:read_file(File), _Wik = {wik002,_Pwd,_Email,_Time, _Who,_Txt,Files,_Patches} = bin_to_wik002(Bin), Extend = fun({file, Name, Desc, _}) -> {file, Name, Desc, []}; ({file, Name, _}) -> {file, Name, "", []} end, OldFiles = [ Extend(F) || F <- Files], CpFiles = [ {file, Name, Desc, []} || {file, Name, Desc, _} <- OldFiles, lists:member(Name, CheckedFiles)], List = wiki_to_html:format_wiki_files(Page, FileDir, lists:keysort(2,CpFiles), Root, "The following files will be copied " "from " ++ Page ++ "."), CpList = [input("hidden", "cp_"++Name, Name) || {file, Name, _, _} <- CpFiles], PageFiles = sort(files(Root, "\\.wob$")), Pages = [filename:basename(P,".wob") || P <- PageFiles, P /= File], if length(CheckedFiles) == 0 -> editFiles(Params, Root, Prefix); true -> template2(Root, "Confirm", Page, [List, form("POST", "copyFiles.yaws", [CpList, "Destination: ", input("select","destination",Pages), input("submit", "copy", "Copy"), input("submit", "cancel", "Cancel"), input("hidden", "node", Page), input("hidden", "password", Password)]) ], false) end. copyFiles(Params, Root, Prefix) -> Password = getopt("password", Params, ""), Page = getnode(Params), Cancel = getopt("cancel", Params), if Cancel /= undefined -> redirect({node, Page}, Prefix); true -> case checkPassword(Page, Password, Root, Prefix) of true -> copyFiles1(Params, Root, Prefix); false -> show({bad_password, Page}, Root); error -> show({no_such_page,Page}, Root) end end. copyFiles1(Params, Root, Prefix) -> Page = getnode(Params), Dest = getopt("destination", Params), case checkPassword(Dest, "", Root, Prefix) of true -> copyFiles3(Params, Root, Prefix); false -> getPassword(Dest, Root, Prefix, copyFiles2, Params); error -> show({no_such_page,Page}, Root) end. copyFiles2(Params, Root, Prefix) -> Page = getnode(Params), Dest = getopt("destination", Params), Password = getopt("password", Params, ""), case checkPassword(Dest, Password, Root, Prefix) of true -> copyFiles3(Params, Root, Prefix); false -> show({bad_password, Page}, Root); error -> show({no_such_page,Page}, Root) end. copyFiles3(Params, Root, Prefix) -> Page = getnode(Params), Dest = getopt("destination", Params), {_SrcWobFile, SrcFileDir} = page2filename(Page, Root), {_DstWobFile, DstFileDir} = page2filename(Dest, Root), SrcFileNames = [lists:nthtail(3,N) || {N,_S,_} <- Params, lists:prefix("cp_",N)], SrcDir = Root ++ "/" ++ SrcFileDir ++ "/", DstDir = Root ++ "/" ++ DstFileDir ++ "/", [os:cmd("cp '"++SrcDir++F++"' '"++DstDir++"'") || F <- SrcFileNames], importFiles(Dest, Root, Prefix). store_ok(Page, _Root, Prefix, OldTxt, {wik002,_Pwd,_Email,_Time,_Who,OldTxt,_Files,_Patches}) -> redirect({node, Page}, Prefix); store_ok(Page, Root, Prefix, NewTxt, {wik002,Pwd,Email,_Time,_Who,OldTxt,Files,Patches}) -> Patch = wiki_diff:diff(NewTxt, OldTxt), Time = {date(), time()}, Who = "unknown", Patches1 = [{Patch,Time,Who}|Patches], Ds = {wik002,Pwd, Email,Time,Who,NewTxt,Files,Patches1}, B = term_to_binary(Ds), {File,_FileDir} = page2filename(Page, Root), file:write_file(File, B), redirect({node, Page}, Prefix). showHistory(Params, Root, _Prefix) -> Page = getnode(Params), {File,_FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> {wik002,_Pwd,_Email,_Time,_Who,_OldTxt,_Files,Patches} = bin_to_wik002(Bin), Links = reverse(mk_history_links(reverse(Patches), Page, 1)), template2(Root, "History", Page, Links, false); _ -> show({no_such_page, Page}, Root) end. redirect({node, Page}, Prefix) -> {redirect_local, Prefix++"showPage.yaws?node="++str2urlencoded(Page)}. redirect_files(Page, Password, Prefix) -> {redirect_local, Prefix++"editFiles.yaws?node="++str2urlencoded(Page)++ "&password="++str2urlencoded(Password)}. redirect_edit(Page, Sid, Password, Prefix) -> UrlSid = str2urlencoded(Sid), UrlPW = str2urlencoded(Password), {redirect_local, Prefix++"editPage.yaws?node="++str2urlencoded(Page)++ "&sid="++UrlSid++"&password="++UrlPW}. redirect_create(Page, Sid, Prefix) -> UrlSid = str2urlencoded(Sid), {redirect_local, Prefix++"createNewPage.yaws?node="++str2urlencoded(Page)++ "&sid="++UrlSid}. redirect_change(Page, Prefix) -> {redirect_local, Prefix++"changePassword.yaws?node="++ str2urlencoded(Page)}. mk_history_links([{C,Time,_Who}|T], Page, N) -> [["<li>",i2s(N)," modified on <a href='showOldPage.yaws?node=", str2urlencoded(Page), "&index=",i2s(N), "'>",format_time(Time),"</a> size ", i2s(size(C)), " bytes", "\n"]|mk_history_links(T, Page, N+1)]; mk_history_links([], _, _) -> []. format_time({{Year,Month,Day},{Hour,Min,Sec}}) -> [i2s(Year),"-",i2s(Month),"-",i2s(Day)," ", i2s(Hour),":",i2s(Min),":",i2s(Sec)]. allPages(_, Root, _Prefix) -> Files = sort(files(Root, "\\.wob$")), template2(Root, "All Pages", "All Pages", [p("This is a list of all pages known to the system."), lists:map(fun(I) -> F = filename:basename(I, ".wob"), [wiki_to_html:format_link(F, Root), "<br>"] end, Files)], false). lastEdited(_, Root, _Prefix) -> Files = sort(files(Root, "\\.wob$")), _S = lists:flatten(lists:map(fun(I) -> "~" ++ filename:basename(I, ".wob") ++"\n\n" end, Files)), V = reverse(sort( lists:map(fun(I) -> {last_edited_time(I), I} end, Files))), Groups = group_by_day(V), S1 = lists:map(fun({{Year,Month,Day},Fx}) -> [p(),i2s(Year),"-",i2s(Month),"-",i2s(Day),"<p>", "<ul>", lists:map(fun(F) -> F1 = filename:basename(F, ".wob"), J = wiki_to_html:format_link(F1, Root), [J,"<br>"] end, Fx), "</ul>"] end, Groups), template2(Root,"Last Edited", "These are the last edited files", S1, false). group_by_day([]) -> []; group_by_day([{{Day,_Time}, File}|T]) -> {Stuff, T1} = collect_this_day(Day, T, [File]), T2 = group_by_day(T1), [Stuff|T2]. collect_this_day(Day, [{{Day,_Time},File}|T], L) -> collect_this_day(Day, T, [File|L]); collect_this_day(Day, T, L) -> {{Day,reverse(L)}, T}. last_edited_time(File) -> case file:read_file(File) of {ok, Bin} -> {wik002,_Pwd,_Email,Time,_Who,_Txt,_Files,_Patches} = bin_to_wik002(Bin), Time; _ -> error end. showOldPage(Params, Root, _Prefix) -> Page = getnode(Params), Nt = getopt("index", Params), case catch list_to_integer(Nt) of {'EXIT', _Reason} -> show({no_such_index, Nt}, Root); Index when is_integer(Index) -> {File,FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> _Wik = {wik002,_Pwd,_Email,_Time,_Who,Txt,Files,Patches} = bin_to_wik002(Bin), %% N = #patches to do N = length(Patches) - Index + 1, ThePatches = take(N, Patches), TxtStr = wiki_diff:patchL(Txt, ThePatches), W = wiki_split:str2wiki(TxtStr), DeepStr = wiki_to_html:format_wiki(Page, W, Root), DeepFiles = wiki_to_html:format_wiki_files( Page, FileDir,Files, Root), Form = form("POST", "noop.yaws", [textarea("text", 25, 75, TxtStr)]), wiki_templates:template2(Root, Page, Page, [DeepStr,DeepFiles,"<hr>", Form], false); _ -> show({no_such_page, Page}, Root) end end. take(0, _) -> []; take(N, [{P,_,_}|T]) -> [P|take(N-1, T)]. deletePage(Params, Root, Prefix) -> Page = getnode(Params), Password = getopt("password", Params, ""), case checkPassword(Page, Password, Root, Prefix) of true -> deletePage1(Params, Root, Prefix); false -> show({bad_password, Page}, Root); error -> show({no_such_page,Page}, Root) end. deletePage1(Params, Root, _Prefix) -> Page = getnode(Params), Password = getopt("password", Params), {File,_FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> {wik002, _Pwd,_Email,_Time,_Who,Content,_Files,_Patches} = bin_to_wik002(Bin), template2(Root, "Delete", Page, [p("Reconfirm deleting this page - hit the 'Delete' " "button to permanently remove the page."), form("POST", "finalDeletePage.yaws", [input("submit", "finaldelete", "Delete"), input("submit", "cancel", "Cancel"), input("hidden", "node", Page), input("hidden", "password", Password), p(), textarea("text", 25, 75, Content), p(), hr()])], false); _ -> show({no_such_page,Page}, Root) end. finalDeletePage(Params, Root, Prefix) -> Page = getnode(Params), Password = getopt("password", Params, ""), Cancel = getopt("cancel", Params), if Cancel /= undefined -> redirect({node, Page}, Prefix); true -> case checkPassword(Page, Password, Root, Prefix) of true -> finalDeletePage1(Params, Root, Prefix); false -> show({bad_password, Page}, Root); error -> show({no_such_page,Page}, Root) end end. finalDeletePage1(Params, Root, Prefix) -> Page = getnode(Params), _Txt0 = getopt("text", Params), {File,FileDir} = page2filename(Page, Root), case file:delete(File) of ok -> Files = files(Root++"/"++FileDir, "^"), [file:delete(F) || F <- Files], file:del_dir(Root++"/"++FileDir), redirect({node, "home"}, Prefix); _ -> wiki_templates:template2(Root, "Error", Page, [p("Failed to delete page."), hr()], false) end. getPassword(Page, Root, _Prefix, Target, Values) -> Vs = [{"target", atom_to_list(Target), []}| lists:keydelete("password", 1, Values)], Hidden = [[input("hidden", Name, Value),"\n"] || {Name, Value, _} <- Vs], template2(Root, "Password", Page, [p("This page is password protected - provide a password " "and hit the 'Continue' button."), form("POST", "putPassword.yaws","f", (Hidden ++ [input("hidden", "target", atom_to_list(Target)), "Password: ", password_entry("password",8), input("submit","continue","Continue"), input("submit","cancel","Cancel"), script("document.f.password.focus();") ] ) ) ], false). putPassword(Params, Root, Prefix) -> Target = getopt("target", Params, "error"), Cancel = getopt("cancel", Params), Page = getnode(Params), if Cancel /= undefined -> redirect({node, Page}, Prefix); true -> case Target of "error" -> show({no_such_target, Target}, Root); _ -> apply(?MODULE,list_to_atom(Target),[Params, Root, Prefix]) end end. editPage(Params, Root, Prefix) -> Password = getopt("password", Params, ""), Page = getnode(Params), Sid = getopt("sid", Params), case checkPassword(Page, Password, Root, Prefix) of true -> editPage(Page, Password, Root, Prefix, Sid); false -> getPassword(Page, Root, Prefix, editPage, Params); error -> show({no_such_page,Page}, Root) end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Session manager %% -record(sid, {text="", password="", email=""}). session_server_ensure_started() -> case whereis(wiki_session_manager) of undefined -> Pid = spawn(?MODULE, session_manager_init, [0,[]]), register(wiki_session_manager, Pid); _ -> done end. session_manager_init(N,Sessions) -> process_flag(trap_exit, true), session_manager(N,Sessions). % Sessions = [{Pid, Sid}] session_manager(N,Sessions) -> receive {'EXIT', Pid, _} -> NewS = lists:keydelete(Pid, 1, Sessions), session_manager(N, NewS); {Sid, stop} -> NewS = lists:keydelete(Sid, 2, Sessions), case lists:keysearch(Sid, 2, Sessions) of {value, {Pid, Sid}} -> Pid ! done; _ -> do_nothing end, session_manager(N,NewS); {new_sid, From, Txt, Passwd, Email} -> Sid = integer_to_list(N), Pid = spawn_link(?MODULE, session_proc, [Sid,#sid{text=Txt, password=Passwd, email=Email}]), From ! {session_id, Sid}, session_manager(N+1, [{Pid, Sid}|Sessions]); {new_sid, Sid, From, Txt, Passwd, Email} -> case lists:keysearch(Sid, 2, Sessions) of {value, _} -> From ! {session_id, Sid}; _ -> Pid = spawn_link(?MODULE, session_proc, [Sid,#sid{text=Txt, password=Passwd, email=Email}]), From ! {session_id, Sid}, session_manager(N, [{Pid, Sid}|Sessions]) end, session_manager(N, Sessions); {to_sid, From, Sid, Msg} -> case lists:keysearch(Sid, 2, Sessions) of {value, {Pid, Sid}} -> Pid ! Msg; _ -> From ! {unknown_sid, Sid} end, session_manager(N, Sessions); _Unknown -> session_manager(N, Sessions) end. session_proc(Sid,State) -> receive stop -> exit(done); {set_text, From, NewTxt} -> From ! {set, Sid}, session_proc(Sid,State#sid{text=NewTxt}); {get_text, From} -> From ! {text, Sid, State#sid.text}, session_proc(Sid,State); {set_all, From, NewTxt, NewPW, NewEmail} -> From ! {set, Sid}, session_proc(Sid,State#sid{text=NewTxt, password=NewPW, email=NewEmail}); {get_all, From} -> From ! {all, Sid, State#sid.text, State#sid.password, State#sid.email}, session_proc(Sid,State) after 3600000 -> %% one hour exit(timeout) end. to_sm(Msg) -> session_server_ensure_started(), wiki_session_manager ! Msg. session_end(undefined) -> done; session_end(Sid) -> to_sm({to_sid, self(), Sid, stop}). session_new(Txt) -> session_new(Txt, "", ""). session_new(Sid, Txt) -> session_new(Sid, Txt, "", ""). session_new(Txt, Passwd, Email) -> to_sm({new_sid, self(), Txt, Passwd, Email}), receive {session_id, Sid} -> Sid end. session_new(Sid, Txt, Passwd, Email) -> to_sm({new_sid, Sid, self(), Txt, Passwd, Email}), receive {session_id, Sid} -> Sid end. session_get_text(undefined, OldTxt) -> OldTxt; session_get_text(Sid, OldTxt) -> to_sm({to_sid, self(), Sid, {get_text, self()}}), receive {text, Sid, Txt} -> Txt; {unknown_sid, Sid} -> session_new(Sid, OldTxt), OldTxt end. session_set_text(undefined, _) -> done; session_set_text(Sid, Txt) -> to_sm({to_sid, self(), Sid, {set_text, self(), Txt}}), receive {set, Sid} -> done; {unknown_sid, Sid} -> session_new(Sid, Txt) end. session_get_all(undefined, Txt, Passwd, Email) -> {Txt,Passwd,Email}; session_get_all(Sid, Txt, Passwd, Email) -> to_sm({to_sid, self(), Sid, {get_all, self()}}), receive {all, Sid, OldTxt, OldPasswd, OldEmail} -> {OldTxt, OldPasswd, OldEmail}; {unknown_sid, Sid} -> session_new(Sid, Txt, Passwd, Email), {Txt, Passwd, Email} end. session_set_all(undefined, _,_,_) -> done; session_set_all(Sid, Txt, Passwd, Email) -> to_sm({to_sid, self(), Sid, {set_all, self(), Txt, Passwd, Email}}), receive {set, Sid} -> done; {unknown_sid, Sid} -> session_new(Sid, Txt, Passwd, Email) end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% editPage(Page, Password, Root, Prefix, Sid) -> {File,_FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> {wik002, _Pwd,_Email,_Time,_Who,TxtStr,_Files,_Patches} = bin_to_wik002(Bin), if Sid /= undefined -> OldTxt = session_get_text(Sid, TxtStr), edit1(Page, Root, Password, OldTxt, Sid); true -> NewSid = session_new(TxtStr), redirect_edit(Page, NewSid, Password, Prefix) end; _ -> show({no_such_page,Page}, Root) end. edit1(Page, Root, Password, Content, Sid) -> template2(Root, "Edit", Page, [p("Edit this page - when you have finished hit the 'Preview' " "button to check your results."), form("POST", "previewPage.yaws?sid="++str2urlencoded(Sid), "f1", [textarea("text", 25, 75, Content), p(), input("submit", "preview", "Preview"), input("submit", "delete", "Delete"), input("submit", "cancel", "Cancel"), input("submit", "chpasswd", "Password"), input("hidden", "node", Page), input("hidden", "password", Password), hr()]) ], false). sendMeThePassword(Params, Root, _Prefix) -> Page = getnode(Params), Email = getopt("email", Params), {File,_FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> {wik002,Pwd,EmailOwner,_Time,_Who,_OldTxt,_Files,_Patches} = bin_to_wik002(Bin), %% io:format("Here Email=~p EMailOwner=~p~n",[Email,EmailOwner]), case Email of "" -> template2(Root, "Error", "Failure", [p("This page has no associated email address")], false); EmailOwner -> mail(Page, Email, Pwd), template2(Root, "Ok", "Success", [p("The password has been mailed to "), Email, p("Have a nice day")], false); _Other -> template2(Root, "Error", "Failure", [p("Incorrect email address")], false) end; _ -> show({no_such_file,Page}, Root) end. checkPassword(Page, Password, Root, _Prefix) -> {File,_FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> {wik002, Pwd,_Email,_Time,_Who,_TxtStr,_Files,_Patches} = bin_to_wik002(Bin), case Pwd of "" -> true; Password -> true; _ -> false end; _ -> error end. editFiles(Params, Root, Prefix) -> Page = getnode(Params), Password = getopt("password", Params, ""), case checkPassword(Page, Password, Root, Prefix) of true -> editFiles1(Page, Password, Root, Prefix); false -> getPassword(Page, Root, Prefix, editFiles, Params); error -> show({no_such_page,Page}, Root) end. editFiles1(Page, Password, Root, _Prefix) -> {File,_FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> {wik002,_Pwd,_Email,_Time,_Who,_OldTxt,Files,_Patches} = bin_to_wik002(Bin), CheckBoxes = lists:map(fun({file,Name,Description,_Content}) -> ["<tr><td align=left valign=top>", input("checkbox","cb_"++Name,"on", ""), yaws_api:htmlize(Name), "</td><td width='70%' align=left " "valign=top>", textarea("cbt_"++Name, 2, 20, Description), "</td></tr>\n"]; ({file,Name,_Content}) -> ["<tr><td align=left valign=top>", input("checkbox","cb_"++Name,"on", ""), yaws_api:htmlize(Name), "</td><td width='70%' align=left " "valign=top>", textarea("cbt_"++Name, 2, 20, ""), "</td></tr>\n"] end, lists:keysort(2,Files)), Check = ["Check files that you want to operate on:", p(), "<table cellspacing=10 width = \"100%\">\n", CheckBoxes, "</table>\n", p(), hr()], wiki_templates:template2(Root, "Edit", Page, [form("POST", "storeFiles.yaws", [Check, input("submit", "add", "Add"), input("submit", "update", "Update"), input("submit", "delete", "Delete"), input("submit", "copy", "Copy"), input("submit", "cancel", "Done"), input("hidden", "node", Page), input("hidden", "password", Password) ])], false); _Error -> show({no_such_page, Page}, Root) end. slideShow(Params, Root, Prefix) -> Page = getnode(Params), NextArg = getopt("next", Params, undefined), PrevArg = getopt("prev", Params, undefined), AutoArg = getopt("auto", Params, undefined), case {NextArg, PrevArg, AutoArg} of {undefined, undefined, undefined} -> nextSlide(1, next, Page, Root, Prefix); {undefined, undefined, _} -> Index = case catch list_to_integer(AutoArg) of {'EXIT', _Reason} -> 1; Num when is_integer(Num) -> Num end, nextSlide(Index, auto, Page, Root, Prefix); {undefined, _, undefined} -> Index = case catch list_to_integer(PrevArg) of {'EXIT', _Reason} -> 1; Num when is_integer(Num) -> Num end, nextSlide(Index, prev, Page, Root, Prefix); {_, undefined, undefined} -> Index = case catch list_to_integer(NextArg) of {'EXIT', _Reason} -> 1; Num when is_integer(Num) -> Num end, nextSlide(Index, next, Page, Root, Prefix) end. nextSlide(Index, Direction, Page, Root, Prefix) -> {File,FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> {wik002, Pwd,_Email,Time,_Who,_TxtStr,Files,_Patches} = bin_to_wik002(Bin), case get_img(Index, Direction, lists:keysort(2,Files)) of false -> % done redirect({node, Page}, Prefix); {ok, NewIndex, PictFile} -> FileName = element(2, PictFile), Comment = element(3, PictFile), Node = str2urlencoded(Page), DeepStr = ["<table width='100%'>" "<tr><td valign=middle>" "<a href=\"slideShow.yaws?node=", Node,"&prev=", integer_to_list(NewIndex-1),"\">" "<img align=middle border=0 src='WikiPreferences.files/back.gif' " "alt='Back' title='Previous Image'>" "</a> ", build_slide_list(Node, NewIndex, length(Files)), "<a href=\"slideShow.yaws?node=",Node,"&next=", integer_to_list(NewIndex+1),"\">" "<img align=middle border=0 src='WikiPreferences.files/forward.gif' " "alt='Next' title='Next Image'>" "</a> " "<a href=\"slideShow.yaws?node=",Node,"&auto=", integer_to_list(NewIndex+1),"\">" "<img align=middle border=0 src='WikiPreferences.files/kamera.gif' " "alt='Play' title='Show slideshow'>" "</a> " "<a href=\"thumbIndex.yaws?node=",Node,"\">" "<img align=middle border=0 src='WikiPreferences.files/index.gif' " "alt='Thumbnails' title='All images'>" "</a> " "</td></tr></table>" "<p><b>",integer_to_list(NewIndex)," - ", yaws_api:htmlize(Comment),"</b></p><p>", "<a href=\"", wiki:str2urlencoded(FileDir), "/", wiki:str2urlencoded(FileName),"\" target=\"pict\">", "<img src=\"getMidSize.yaws?node=", Node,"&pict=", wiki:str2urlencoded(FileName), "\" alt='",FileName, "'></a></p>Click on image to enlarge."], Auto = if Direction==auto -> ["<META HTTP-EQUIV=\"REFRESH\" " "CONTENT=\"10; URL=slideShow.yaws?node=", Node,"&auto=",integer_to_list(NewIndex+1), "\">"]; true -> [] end, F1 = add_blanks_nicely(Page), _TopHeader = ["<a href='showPage.yaws?node=", str2urlencoded(Page), "'>",yaws_api:htmlize(F1),"</a>\n"], Locked = Pwd /= "", _Link = wiki_templates:template(Page, Root, [DeepStr, Auto], utils:time_to_string(Time), Locked) end; _ -> show({no_such_page,Page}, Root) end. thumbIndex(Params, Root, Prefix) -> Page = getnode(Params), {File,FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> {wik002, Pwd,_Email,Time,_Who,_TxtStr,Files,_Patches} = bin_to_wik002(Bin), {NumFiles,_} = lists:mapfoldl( fun(F,N) -> {{element(2,F),N}, N+1} end, 1, lists:keysort(2,Files)), Pics = [{F,N} || {F,N} <- NumFiles, pict_suffix(F)], Node = str2urlencoded(Page), DeepStr = ["<table>", build_thumb_table(Pics, Node, Prefix, Root, FileDir), "</table>"], F1 = add_blanks_nicely(Page), _TopHeader = ["<a href='showPage.yaws?node=",Node,"'>", yaws_api:htmlize(F1),"</a>\n"], Locked = Pwd /= "", _Link = wiki_templates:template(Page, Root, DeepStr, utils:time_to_string(Time), Locked); _ -> show({no_such_page,Page}, Root) end. build_thumb_table([], _Node, _Prefix, _Root, _FileDir) -> []; build_thumb_table(Pics, Node, Prefix, Root, FileDir) -> build_thumb_rows(Pics, Node, Prefix, Root, FileDir, 0, 5, ["<tr>"]). build_thumb_rows([], _Node, _Prefix, _Root, _FileDir, _, _, Acc) -> lists:reverse(["</tr>"|Acc]); build_thumb_rows(Pics, Node, Prefix, Root, FileDir, X, X, Acc) -> build_thumb_rows(Pics, Node, Prefix, Root, FileDir, 0, X, ["</tr>\n<tr>"|Acc]); build_thumb_rows([{P,Num}|Pics], Node, Prefix, Root, FileDir, N, X, Acc) -> ThumbName = thumb_name(P), SrcPath = Root++"/"++FileDir++"/"++P, DstPath = Root++"/"++FileDir++"/"++ThumbName, create_thumb_if_needed(SrcPath, DstPath), Img = Prefix++str2urlencoded(FileDir)++"/"++str2urlencoded(ThumbName), build_thumb_rows(Pics, Node, Prefix, Root, FileDir, N+1, X, [lists:append(["<td align=\"center\">" "<a href=\"slideShow.yaws?node=", Node, "&next=",integer_to_list(Num),"\">" "<img src='",Img, "'></a></td>\n"])|Acc]). build_slide_list(Node, _Index, Nr) when Nr =< 10 -> Interval = 1, lists:flatmap( fun(X) -> I = integer_to_list(X), [" <a href=\"slideShow.yaws?node=",Node,"&next=",I,"\">", I,"</a> "] end, lists:seq(1,Nr,Interval)); build_slide_list(Node, _Index, Nr) -> lists:flatmap( fun(X) -> I = if X==0 -> "1" ; true -> integer_to_list(X) end, [" <a href=\"slideShow.yaws?node=",Node,"&next=",I,"\">", I,"</a> "] end, lists:seq(0,Nr,5)). lowercase([C|S]) -> [lowercase(C)|lowercase(S)]; lowercase(C) when C>=$A, C=<$Z -> C+32; lowercase(C) -> C. pict_suffix(File) -> lists:member(lowercase(filename:extension(File)), [".gif", ".jpeg", ".jpe", ".jpg"]). get_img(Index, Direction, Files) -> case catch lists:nth(Index, Files) of {'EXIT', _} -> false; PictFile -> FileName = element(2, PictFile), case lowercase(lists:reverse(FileName)) of "fig."++_ -> {ok, Index, PictFile}; "gepj."++_ -> {ok, Index, PictFile}; "gpj."++_ -> {ok, Index, PictFile}; _Any -> if Direction == next -> get_img(Index+1, Direction, Files); Direction == auto -> get_img(Index+1, Direction, Files); true -> get_img(Index-1, Direction, Files) end end end. editTag(Params, Root, _Prefix) -> Page = getnode(Params), Tag = getopt("tag", Params), case catch list_to_integer(Tag) of {'EXIT', _Reason} -> show({no_such_tag, Tag}, Root); ITag when is_integer(ITag) -> {File,_FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> {wik002,_Pwd,_Email,_Time,_Who,OldTxt,_Files,_Patches} = bin_to_wik002(Bin), Wik = wiki_split:str2wiki(OldTxt), {Type, Str} = wiki_split:getRegion(ITag, Wik), Str1 = case Type of open -> Str; write_append -> "" end, wiki_templates:template2(Root, "Edit", Page, [p("Edit this page - when you have finished hit the " "'Preview' button to check your results."), form("POST", "previewTagged.yaws", [input("submit", "review", "preview"), input("hidden", "node", Page), input("hidden", "tag", Tag), p(), textarea("text", 25, 75, Str1), p(), hr()])], false); _Error -> show({no_such_page, Page}, Root) end end. changePassword(Params, Root, _Prefix) -> Page = getnode(Params), wiki_templates:template2( Root, "Edit", Page, [p("Change password setting for page - to remove a password leave " "the new passwords blank."), form("POST", "changePassword2.yaws?node="++ str2urlencoded(Page), "f", ["<table>\n" "<tr> <td align=left> Old password: </td>" "<td aligh=left> ", password_entry("password", 8), "</td></tr>\n" "<tr> <td align=left>New password: </td>" "<td aligh=left> ", password_entry("password1", 8), "</td></tr>\n" "<tr> <td align=left>Reconfirm password: </td>" "<td aligh=left> ", password_entry("password2", 8), "</td></tr>\n" "</table>", input("submit", "change", "Change"), script("document.f.password.focus();") ] ) ], false). changePassword2(Params, Root, Prefix) -> Page = getnode(Params), OldPw = getopt("password", Params), Pw1 = getopt("password1", Params), Pw2 = getopt("password2", Params), {File,_FileDir} = page2filename(Page, Root), case file:read_file(File) of {ok, Bin} -> {wik002,Pwd,Email,Time,Who,Txt,Files,Patches} = bin_to_wik002(Bin), if OldPw == Pwd -> if Pw1 == Pw2 -> Ds = {wik002,Pw1,Email,Time,Who,Txt,Files,Patches}, B = term_to_binary(Ds), file:write_file(File, B), redirect({node, Page}, Prefix); true -> show({password_mismatch, Page}, Root) end; true -> show({bad_password, Page}, Root) end; _Error -> show({no_such_page, Page}, Root) end. previewPage(Params, Root, Prefix) -> Page = getnode(Params), Cancel = getopt("cancel", Params), Delete = getopt("delete", Params), Change = getopt("chpasswd", Params), Sid = getopt("sid", Params), if Cancel /= undefined -> session_end(Sid), redirect({node, Page}, Prefix); Delete /= undefined -> session_end(Sid), deletePage(Params, Root, Prefix); Change /= undefined -> session_end(Sid), redirect_change(Page, Prefix); true -> previewPage1(Params, Root, Prefix) end. previewPage1(Params, Root, _Prefix) -> Page = getnode(Params), Password = getopt("password", Params), Txt0 = getopt("text", Params), Sid = getopt("sid", Params,"undefined"), Txt = zap_cr(Txt0), Wik = wiki_split:str2wiki(Txt), session_set_text(Sid, Txt), template2(Root, "Preview", Page, [p("If this page is ok hit the \"Store\" button " "otherwise return to the editing phase by clicking the edit " "button."), form("POST", "storePage.yaws?sid="++str2urlencoded(Sid), [input("submit", "store", "Store"), input("submit", "cancel", "Cancel"), input("submit", "edit", "Edit"), input("hidden", "node", Page), input("hidden", "password", Password), input("hidden", "txt", str2formencoded(Txt))]), p(),hr(),h1(Page), wiki_to_html:format_wiki(Page, Wik, Root, preview)], false). %% Preview Tagged %% Tagged stuff is inside comment and append regions %% We *dont* want any structure here previewTagged(Params, Root, _Prefix) -> Page = getnode(Params), Tag = getopt("tag", Params), Txt0 = getopt("text", Params), Txt = zap_cr(Txt0), %% we want this stuff to *only* be txt %% io:format("Here previewTagged:~p~n",[Txt]), case legal_flat_text(Txt) of true -> wiki_templates:template2( Root, "Preview", p("If this region is ok hit the \"Store\" button " "otherwise return to the editing phase by clicking " "the back button in your browser."), [form("POST", "storeTagged.yaws", [input("submit", "store", "Store"), input("hidden", "node", Page), input("hidden", "tag", Tag), input("hidden", "txt", str2formencoded(Txt))]), p(),hr(), wiki_to_html:format_wiki(Page,{txt,10000,Txt},Root)], false); false -> show({text_contains,'< or >', in_col_1_which_is_illegal}, Root) end. %% Flat text is *not* allowed to contain < legal_flat_text("<" ++ _) -> false; legal_flat_text(X) -> legal_flat_text1(X). legal_flat_text1("\n<" ++ _) -> false; legal_flat_text1("\n>" ++ _) -> false; legal_flat_text1([_|T]) -> legal_flat_text1(T); legal_flat_text1([]) -> true. previewNewPage(Params, Root, _Prefix) -> Page = getnode(Params), P1 = getopt("password1", Params), P2 = getopt("password2", Params), Email = getopt("email", Params), Txt0 = getopt("text", Params), Sid = getopt("sid", Params), Txt = zap_cr(Txt0), Wik = wiki_split:str2wiki(Txt), session_set_text(Sid, Txt), if P1 == P2 -> session_set_all(Sid,Txt,P1,Email), template2(Root, "Preview", p("If this page is ok hit the \"Store\" button " "otherwise return to the editing phase by clicking " "the back button in your browser."), [form("POST", "storeNewPage.yaws", [input("submit", "store", "Store"), input("hidden", "node", Page), input("hidden", "password", P1), input("hidden", "email", str2formencoded(Email)), input("hidden", "txt", str2formencoded(Txt))]), wiki_to_html:format_wiki(Page, Wik, Root)], false); true -> show({passwords_differ,P1,P2}, Root) end. zap_cr([$\r,$\n|T]) -> [$\n|zap_cr(T)]; zap_cr([H|T]) -> [H|zap_cr(T)]; zap_cr([]) -> []. wikiZombies(_, Root, _Prefix) -> wiki_utils:zombies(Root). allRefsToMe(Params, Root, _Prefix) -> Page = getnode(Params), wiki_utils:findallrefsto(Page, Root). mail(Page, Email, Pwd) -> send(Email,"Wiki password", "The password of " ++ Page ++ " is " ++ Pwd ++ "\n"). send(To, Subject, Data) -> {TmpFile, S} = open_tmp_file("/tmp", ".mail"), io:format(S, "To: <~s>~n", [To]), io:format(S, "Subject: ~s~n~n", [Subject]), io:format(S, "~s~n",[Data]), io:format(S, ".~nquit~n", []), file:close(S), io:format("sending ...~n", []), os:cmd("/usr/sbin/sendmail -t > /dev/null < " ++ TmpFile), file:delete(TmpFile). open_tmp_file(RootName, Suffix) -> open_tmp_file(10, RootName, Suffix). open_tmp_file(0, _, Suffix) -> exit({cannot_open_a_temporay_file, Suffix}); open_tmp_file(N, RootName, Suffix) -> {_,_,M} = erlang:now(), FileName = RootName ++ "/" ++ integer_to_list(M) ++ Suffix, %% io:format("trying to open:~p~n", [FileName]), case file:open(FileName, write) of {ok, Stream} -> {FileName, Stream}; {error, _} -> open_tmp_file(N-1, RootName, Suffix) end. ls(Root) -> Files = files(Root, "\\.wob$"), lists:map(fun(I) -> filename:basename(I, ".wob") end, Files). %% page2filename(Page, Root) -> {Root ++ "/" ++ Page ++ ".wob", Page ++ ".files"}. %% html_error(invalid_request) -> {html, "invalid request"}. %% bin_to_wik002(Bin) -> case binary_to_term(Bin) of {wik001,Pwd,Email,Time,Who,OldTxt,Patches} -> {wik002,Pwd,Email,Time,Who,OldTxt,[],Patches}; {wik002,Pwd,Email,Time,Who,OldTxt,Files,Patches} -> {wik002,Pwd,Email,Time,Who,OldTxt,Files,Patches} end. bin_to_wik002(Root, FileDir, Bin) -> %% First check filedir for files, if empty use files from wob Wik = bin_to_wik002(Bin), case get_wiki_files(Root, FileDir) of [] -> {wik002,_,_,_,_,_,Files,_} = Wik, create_wiki_files(Root, FileDir, Files); _ -> ok end, Wik. %% get_wiki_files(Root, FileDir) -> Dir = Root ++ "/" ++ FileDir, files(Dir, "^"). %% create_wiki_files(Root, FileDir, Files) -> Dir = Root ++ "/" ++ FileDir, file:make_dir(Dir), F = fun({file,F,_D,C}) -> file:write_file(Dir++"/"++F, C); ({file,F,C}) -> file:write_file(Dir++"/"++F, C) end, lists:foreach(F, Files), ok. %% password_entry(Name, Size) -> ["<INPUT TYPE=password name=", yaws_api:htmlize(Name)," SIZE=", i2s(Size),">\n"]. password_entry(Name, Size, Value) -> ["<INPUT TYPE=password name=", yaws_api:htmlize(Name)," SIZE=", i2s(Size), " Value=\"", Value, "\">\n"]. input(Type="button", Name, OnClick) -> ["<INPUT TYPE=",Type," Value=\"",yaws_api:htmlize(Name),"\" onClick=\"", yaws_api:htmlize(OnClick), "\">\n"]; input(Type="file", Name, Size) -> ["<INPUT TYPE=",Type," Name=\"",yaws_api:htmlize(Name),"\" Size=\"", yaws_api:htmlize(Size), "\">\n"]; input(Type="checkbox", Name, Value) -> ["<INPUT TYPE=",Type," Name=\"",yaws_api:htmlize(Name),"\" Value=\"", yaws_api:htmlize(Value), "\" checked>\n"]; input("select", Name, Values) -> Options = ["<option>" ++ yaws_api:htmlize(Option) ++ "</option>" || Option <- Values], ["<select Name=\"",yaws_api:htmlize(Name),"\">\n", Options, "</select>\n"]; input(Type, Name, Value) -> ["<INPUT TYPE=",yaws_api:htmlize(Type)," Name=\"",yaws_api:htmlize(Name),"\" Value=\"", yaws_api:htmlize(Value), "\">\n"]. input(Type="checkbox", Name, Value, State) -> ["<INPUT TYPE=",Type," Name=\"",yaws_api:htmlize(Name),"\" Value=\"", yaws_api:htmlize(Value), "\" " ++ yaws_api:htmlize(State) ++ ">\n"]; input(Type, Name, Value, Size) -> ["<INPUT TYPE=",yaws_api:htmlize(Type)," Name=\"",yaws_api:htmlize(Name),"\" Value=\"", yaws_api:htmlize(Value),"\"", "Size=\"",yaws_api:htmlize(Size), "\">\n"]. script(Script) -> ["<script>\n", Script, "\n</script>\n"]. form(Method, Action, Args) -> ["<FORM METHOD=", Method, " ENCTYPE=\"multipart/form-data\"", " ACTION=\"", yaws_api:htmlize(Action), "\">", Args, "</form>\n"]. form(Method, Action, Name, Args) -> ["<FORM METHOD=", Method, " ENCTYPE=\"multipart/form-data\"", " ACTION=\"", yaws_api:htmlize(Action), "\" NAME=\"", yaws_api:htmlize(Name), "\">", Args, "</form>\n"]. textarea(Name, Row, Txt) -> ["<textarea name=\"", yaws_api:htmlize(Name), "\" rows=", i2s(Row), " wrap=virtual>", yaws_api:htmlize(Txt), "</textarea>\n"]. textarea(Name, Row, Cols, Txt) -> ["<textarea name=\"", yaws_api:htmlize(Name), "\" rows=", i2s(Row), " cols=", i2s(Cols), " wrap=virtual>", yaws_api:htmlize(Txt), "</textarea>\n"]. h1(X) -> ["<h1>",yaws_api:htmlize(X),"</h1>"]. b(X) -> ["<b>",yaws_api:htmlize(X),"</b>"]. p() -> "<p>". p(X) -> ["<p>", yaws_api:htmlize(X), "</p>\n"]. br() -> ["<br>\n"]. hr() -> ["<hr>\n"]. body(X) -> ["<body bgcolor=\"", yaws_api:htmlize(X), "\">"]. pre(X) -> ["<pre>",yaws_api:htmlize(X),"</pre>"]. i2s(I) -> integer_to_list(I). initial_page_content() -> "\nEnter your text here\n". bgcolor(C) -> ["<body bgcolor='", yaws_api:htmlize(C), "'>\n"]. top_header(Page) -> F1 = add_blanks_nicely(Page), ["<h1><a href='allRefsToMe.yaws?node=",str2urlencoded(Page), "'>",yaws_api:htmlize(F1),"</a></h1>\n"]. add_blanks_nicely([H1,H2|T]) -> case {little_letter(H1), big_letter(H2)} of {true,true} -> [H1,$ ,H2|add_blanks_nicely(T)]; _ -> [H1|add_blanks_nicely([H2|T])] end; add_blanks_nicely([H|T]) -> [H|add_blanks_nicely(T)]; add_blanks_nicely([]) -> []. big_letter(H) when $A =< H, H =< $Z -> true; big_letter($Ã…) -> true; big_letter($Ä) -> true; big_letter($Ö) -> true; big_letter(_) -> false. little_letter(H) when $a =< H, H =< $z -> true; little_letter($Ã¥) -> true; little_letter($ä) -> true; little_letter($ö) -> true; little_letter(_) -> false. show({bad_password, Page}, Root) -> template2(Root, "Error", "Incorrect password", [p("You have supplied an incorrect password"), p("To find out the the password fill " "in your email address and click on " "\"Show password\". If you are " "the registered owner of this page " "then I will tell you the password."), form("POST", "sendMeThePassword.yaws", [input("hidden", "node", Page), "email address:", input("text", "email", ""), input("submit", "send", "Show password")]) ], false); show({illegal_filename, FileName, Reason}, Root) -> template2(Root, "Error", "Illegal filename", [p("You have supplied an illegal filename: " ++ FileName ++ "."), p(Reason)], false); show(X, _Root) -> {html, [body("white"),"<pre>", yaws_api:htmlize(lists:flatten(io_lib:format("~p~n",[X]))), "</pre>"]}. show_error(Str) -> {html, [body("white"),"<pre>","Error: ",Str,"</pre>"]}. %%---------------------------- %% Utilities %% Notes on the encoding of URI's %% This comes from secition 8.2.1 of RFC1866 %% The default encoding for all forms is `application/x-www-form-urlencoded'. %% A form data set is represented in this media type as follows: %% %% 1. The form field names and values are escaped: space characters are %% replaced by `+', and then reserved characters are escaped as per [URL]; %% that is, non-alphanumeric characters are replaced by `%HH', a percent %% sign and two hexadecimal digits representing the ASCII code of the %% character. Line breaks, as in multi-line text field values, are %% represented as CR LF pairs, i.e. `%0D%0A'. %% %% 2. The fields are listed in the order they appear in the document with the %% name separated from the value by `=' and the pairs separated from each %% other by `&'. Fields with null values may be omitted. In particular, %% unselected radio buttons and checkboxes should not appear in the %% encoded data, but hidden fields with VALUE attributes present should. %% str2fileencoded([$_|T]) -> [$_|str2fileencoded(T)]; str2fileencoded([$ |T]) -> [$ |str2fileencoded(T)]; str2fileencoded([$.|T]) -> [$.|str2fileencoded(T)]; str2fileencoded([H|T]) -> case is_alphanum(H) of true -> [H|str2fileencoded(T)]; false -> {Hi,Lo} = byte2hex(H), [$%,Hi,Lo|str2fileencoded(T)] end; str2fileencoded([]) -> []. fileencoded2str(Str) -> urlencoded2str(Str). str2urlencoded([$\n|T]) -> "%0D%0A" ++ str2urlencoded(T); str2urlencoded([$.|T]) -> "." ++ str2urlencoded(T); str2urlencoded([H|T]) -> case is_alphanum(H) of true -> [H|str2urlencoded(T)]; false -> {Hi,Lo} = byte2hex(H), [$%,Hi,Lo|str2urlencoded(T)] end; str2urlencoded([]) -> []. str2formencoded([$ |T]) -> [$+|str2formencoded(T)]; str2formencoded([$.|T]) -> [$.|str2formencoded(T)]; str2formencoded([$\n|T]) -> "%0D%0A" ++ str2formencoded(T); str2formencoded([H|T]) -> case is_alphanum(H) of true -> [H|str2formencoded(T)]; false -> {Hi,Lo} = byte2hex(H), [$%,Hi,Lo|str2formencoded(T)] end; str2formencoded([]) -> []. byte2hex(X) -> {nibble2hex(X bsr 4), nibble2hex(X band 15)}. nibble2hex(X) when X < 10 -> $0 + X; nibble2hex(X) -> $A + X - 10. is_alphanum(X) when $0 =< X, X =< $9 -> true; is_alphanum(X) when $a =< X, X =< $z -> true; is_alphanum(X) when $A =< X, X =< $Z -> true; is_alphanum(_) -> false. urlencoded2str([$%,Hi,Lo|T]) -> [decode_hex(Hi, Lo)|urlencoded2str(T)]; urlencoded2str([$+|T]) -> [$ |urlencoded2str(T)]; urlencoded2str([H|T]) -> [H|urlencoded2str(T)]; urlencoded2str([]) -> []. %% decode_hex %% decode_hex(Hex1, Hex2) -> hex2dec(Hex1)*16 + hex2dec(Hex2). hex2dec(X) when X >=$0, X =<$9 -> X-$0; hex2dec($A) -> 10; hex2dec($B) -> 11; hex2dec($C) -> 12; hex2dec($D) -> 13; hex2dec($E) -> 14; hex2dec($F) -> 15; hex2dec($a) -> 10; hex2dec($b) -> 11; hex2dec($c) -> 12; hex2dec($d) -> 13; hex2dec($e) -> 14; hex2dec($f) -> 15. %% %% MR: Is this really necessary ? %% We can now use filelib:fold_files/5 files(Dir, Re) -> case re:compile(Re) of {ok, Re1} -> find_files(Dir, Re1, []); _ -> [] end. find_files(Dir, Re, L) -> case file:list_dir(Dir) of {ok, Files} -> find_files(Files, Dir, Re, L); {error, _} -> L end. find_files([File|T], Dir, Re, L) -> FullName = Dir ++ [$/|File], case file_type(FullName) of regular -> case re:run(FullName, Re) of {match, _} -> find_files(T, Dir, Re, [FullName|L]); _ -> find_files(T, Dir, Re, L) end; _ -> find_files(T, Dir, Re, L) end; find_files([], _, _, L) -> L. file_type(File) -> case file:read_file_info(File) of {ok, Facts} -> case element(3, Facts) of regular -> regular; directory -> directory; _ -> error end; _ -> error end. %% read_page(Page, Root) -> {File,_FileDir} = page2filename(Page, Root), %% io:format("Reading:~p~n",[Page]), case file:read_file(File) of {ok, Bin} -> {wik002,_Pwd,_Email,_Time,_Who,OldTxt,_Files,_Patches} = bin_to_wik002(Bin), {ok, OldTxt}; _ -> error end. %% mime_type(Name) -> case lists:reverse(Name) of "cod."++_ -> "application/octet-stream"; "piz."++_ -> "application/x-zip"; "lmth."++_ -> "text/html"; "mth."++_ -> "text/html"; "fdp."++_ -> "application/pdf"; _ -> "application/octet-stream" end. %% %% Applies the Funs in the list to the Args. Return the value of the %% first Fun that returns a non-ok value, otherwise ok. check_precon([],_Args) -> ok; check_precon([F|Fs], Args) -> case apply(F,Args) of ok -> check_precon(Fs, Args); NotOk -> NotOk end. %% getnode(KeyList) -> case getopt("node", KeyList) of Node when is_list(Node)-> case re:run(Node, "^[0-9A-Za-z]+$") of {match, _} -> Node; _ -> undefined end; _ -> undefined end. getopt(Key, KeyList) -> getopt(Key, KeyList, undefined). % getopt(Key, KeyList, Default) when atom (Key) -> % getopt(atom_to_list(Key), KeyList, Default); getopt(Key, KeyList, Default) -> case lists:keysearch(Key, 1, KeyList) of false -> Default; {value, Tuple} -> Val = element(2,Tuple), if Val == undefined -> Default; true -> Val end end. getopt_options(Key, KeyList) when is_atom(Key) -> getopt_options(atom_to_list(Key), KeyList); getopt_options(Key, KeyList) -> case lists:keysearch(Key, 1, KeyList) of {value, Tuple} when size(Tuple) >= 3 -> element(3,Tuple); _ -> undefined end. % basename(FilePath) -> case string:rchr(FilePath, $\\) of 0 -> %% probably not a DOS name filename:basename(FilePath); N -> %% probably a DOS name, remove everything after last \ basename(string:substr(FilePath, N+1)) end. % getPassword([File]) -> case file:read_file(File) of {ok, Bin} -> {wik002,Pwd,_Email,_Time,_Who,_OldTxt,_Files,_Patches} = bin_to_wik002(Bin), io:format("Password is: '~s'\n", [Pwd]), halt(); _ -> io:format("Error - failed to open ~s\n", [File]), halt() end. %% tostring(A) when is_atom(A) -> atom_to_list(A); tostring(S) -> S. % wobfile_to_filedir(Wob) -> WobFile = tostring(Wob), string:substr(WobFile, 1, length(WobFile)-3)++"files". %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% forms(Method, Action, Args) -> ["<FORM METHOD=", Method, " ACTION=\"", Action, "\">", Args, "</form>\n"]. searchPara([Para|Paralist]) -> case Para of {"search", undefined, []} -> []; {"search", Search, []} -> case re:compile(Search) of {ok, _RE} -> Search; {error, Error} -> {error, Error} end; _Other -> searchPara(Paralist) end; searchPara([]) -> []. searchPages(SearchPost, Root, _Prefix) -> case searchPara(SearchPost) of [] -> S0 = [forms("POST", "searchPage.yaws", [input("submit", "searchstart", "Search"), input("text", "search", "")])], template2(Root,"Search", "Wiki page search", [S0, "<hr>", h1("Nothing to find")], false); {error, Error} -> S0 = [forms("POST", "searchPage.yaws", [input("submit", "searchstart", "Search"), input("text", "search", "")])], template2(Root,"Search", "Wiki page search", [S0, "<hr>", h1(io_lib:format("Error in the regular " "expression \"~p\"", [Error]))], false); Search -> Files = sort(files(Root, "\\.wob$")), {Sres, _S} = lists:mapfoldl(fun(F, S) -> {searchPage(F, S), S} end, Search, Files), Sres_sort = reverse(sort(Sres)), S1 = lists:map(fun({Matches, Fx}) -> [p(),i2s(Matches)," ", wiki_to_html:format_link( filename:basename(Fx, ".wob"), Root), "</p>"] end, Sres_sort), S0 = [forms("POST", "searchPage.yaws", [input("submit", "searchstart", "Search"), input("text", "search", Search)])], template2(Root,"Search", "Wiki page search", [S0, "<hr>", h1("Number of matches found per page"), S1], false) end. searchPage(File, Search) -> case file:read_file(File) of {ok, Bin} -> {wik002,_Pwd,_Email,_Time,_Who,Txt,_Files,_Patches} = bin_to_wik002(Bin), {match, Matches} = re:run(Txt, Search), {length(Matches), File}; _ -> io:format("Error - failed to open ~s\n", [File]), {-1, File} end. �����������������yaws-2.0.2/applications/wiki/src/wiki_plugin_dummy.erl����������������������������������������������0000664�0001750�0001750�00000000546�12605311412�020101� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%% File : wiki_plugin_dummy.erl %%% Author : Mickael Remond <mickael.remond@erlang-fr.org> %%% Description : Example "dummy" wiki plugin %%% Created : 20 Oct 2003 by Mickael Remond %%% <mickael.remond@erlang-fr.org> -module(wiki_plugin_dummy). -export([run/2]). run(_Page, _ArgList) -> "<p>Using Dummy Wiki Plugin.</p>". ����������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/src/wiki_utils.erl�����������������������������������������������������0000664�0001750�0001750�00000005701�12605311412�016526� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-module(wiki_utils). %% File : wiki_utils.erl %% Author : Joe Armstrong (joe@bluetail.com) %% : Johan Bevemyr (jb@bluetail.com) %% : Mickael Remond (mickael.remond@erlang-fr.org) %% Purpose : Wiki web utilities %% : Find zombie pages %% : Find all references to a given page -export([findallrefsto/2, zombies/1]). -export([getallrefs/2]). -export([getpages_by_prefix/2]). -import(lists, [filter/2, member/2, reverse/1, sort/1, map/2]). -import(wiki, [p/1, h1/1, show/1]). -import(wiki_templates, [template2/5]). %% HTML structure of the backlink list findallrefsto(Page, Root) -> Pages = getallrefs(Page, Root), template2(Root, "References", "References", ["<p>The following pages contain references to ", wiki_to_html:format_link(Page, Root),".", "<ul>", map(fun(F) -> [wiki_to_html:format_link(F, Root),"<br>"] end, Pages), "</ul>"], false). %% Backlinks list getallrefs(Page, Root) -> All = wiki:ls(Root), Pages = filter(fun(I) -> case wiki:read_page(I, Root) of {ok, Str} -> Links = get_links(Str, []), member(Page, Links); error -> false end end, All), sort(Pages). zombies(Root) -> All = wiki:ls(Root), {Reached, _Missing} = gc(["home"], [], [], Root), %% Missing = Pages refered to but do not exists at all %% This is not an error NotReached = sort(All -- Reached), template2(Root, "Zombies", "Zombies", [p("These pages have no links to them."), "<ul>", map(fun(F) -> [wiki_to_html:format_link(F, Root),"<br>"] end, NotReached), "</ul>"], false). %% Return page name that match a specific prefix getpages_by_prefix(Prefix, Root) -> Files = utils:fold_files(Root, Prefix ++ ".*\.wob", false, fun(F, AccIn)-> [F|AccIn] end, []), Pages = lists:map(fun(I) -> filename:basename(I, ".wob") end, Files), sort(Pages). gc([H|T], Visited, Missing, Root) -> case member(H, Visited) or member(H, Missing) of true -> gc(T, Visited, Missing, Root); false -> case wiki:read_page(H, Root) of {ok, Str} -> Links = get_links(Str, []), gc(Links ++ T, [H|Visited], Missing, Root); error -> gc(T, Visited, [H|Missing], Root) end end; gc([], Visited, Missing, _Root) -> {Visited, Missing}. get_links([$\\,_C|T], L) -> get_links(T, L); get_links([$~|T], L) -> {Link, T1} = wiki_format_txt:collect_wiki_link(T), get_links(T1, [Link|L]); get_links([_|T], L) -> get_links(T, L); get_links([], L) -> L. ���������������������������������������������������������������yaws-2.0.2/applications/wiki/src/wiki_templates.erl�������������������������������������������������0000664�0001750�0001750�00000007741�12605311412�017372� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-module(wiki_templates). -export([template/5, template2/5]). %% B = normal | locked | old template(Node,Root,Data,Modified,Locked) -> MenuId = if Locked == true -> "lockedmenuframe" ; true -> "menuframe" end, File = Root ++ "/WikiPreferences.files/template.html", case wiki:file_type(File) of error -> %% template file missing, create default template WobFile = Root ++ "/WikiPreferences.wob", wiki:addFile([WobFile,"template.html"], false), file:write_file(File,template_file()); _ -> ok end, {ssi, {rel_path,"WikiPreferences.files/template.html"}, "@@", [{"NODE", Node}, {"ALLREFS", "allRefsToMe.yaws?node="++Node}, {"HOME", "showPage.yaws?node=home"}, {"HISTORY", "showHistory.yaws?node="++Node}, {"ALL", "allPages.yaws"}, {"LAST", "lastEdited.yaws"}, {"ZOMBIES", "wikiZombies.yaws"}, {"EDITPAGE", "editPage.yaws?node="++Node}, {"EDITFILES", "editFiles.yaws?node="++Node}, {"DATA", Data}, {"MENUID", MenuId}, {"MODIFIED", Modified}]}. template2(Root,Title,Header,Data,Locked) -> MenuId = if Locked == true -> "lockedmenuframe" ; true -> "menuframe" end, File = Root ++ "/WikiPreferences.files/template_info.html", case wiki:file_type(File) of error -> %% template file missing, create default template WobFile = Root ++ "/WikiPreferences.wob", wiki:addFile([WobFile,"template_info.html"], false), file:write_file(File,template_info_file()); _ -> ok end, {ssi, {rel_path,"WikiPreferences.files/template_info.html"}, "@@", [{"TITLE", Title}, {"HEADER", Header}, {"DATA", Data}, {"MENUID", MenuId}]}. template_file() -> <<"<html> <head> <title> @@NODE@@ </title> <style type=\"text/css\"> <!-- @import url(\"WikiPreferences.files/custom.css\"); --> </style> </head> <body> <table width='100%' border=0> <tr> <td> <table width='100%' border=0> <tr> <!-- the menu --> <td id=\"@@MENUID@@\" valign='top' width='90%'> <table width=\"100%\"><tr><td id=\"menu\"> <a href=\"@@HOME@@\"><img border=0 src='WikiPreferences.files/home.gif' alt='Home' title='Go to initial page'></a>&nbsp;&nbsp; <a href=\"@@HISTORY@@\"><img border=0 src='WikiPreferences.files/history.gif' alt='History' title='History of page evolution'></a>&nbsp;&nbsp; <a href=\"@@ALL@@\"><img border=0 src='WikiPreferences.files/allpages.gif' alt='All Pages' title='Lists all pages on this site'></a>&nbsp;&nbsp; <a href=\"@@LAST@@\"><img border=0 src='WikiPreferences.files/lastedited.gif' alt='Last Edited' title='Site editing history'></a>&nbsp;&nbsp; <a href=\"@@ZOMBIES@@\"><img border=0 src='WikiPreferences.files/zombies.gif' alt='Zombies' title='Unreachable pages'></a>&nbsp;&nbsp; <a href=\"@@EDITPAGE@@\"><img border=0 src='WikiPreferences.files/editme.gif' alt='Edit Me' title='Edit this page'></a>&nbsp;&nbsp; <a href=\"@@EDITFILES@@\"><img border=0 src='WikiPreferences.files/editfiles.gif' alt='Edit Files' title='Edit attached files'></a>&nbsp;&nbsp; </td></tr></table> </td> </tr> <tr> <td> <p>&nbsp;<br> <!-- the generated page --> <h1><a href='@@ALLREFS@@'>@@NODE@@</a></h1> @@DATA@@ <hr><p>Last Modified: @@MODIFIED@@ </td> </tr> </table> </td> <!-- the right hand image --> <td width=10 align='right' valign='top'></td> </tr> </table> </body> </html> ">>. template_info_file() -> <<"<html> <head> <title> @@TITLE@@ </title> <style type=\"text/css\"> <!-- @import url(\"WikiPreferences.files/custom.css\"); --> </style> </head> <body> <table width='100%' border=0> <tr> <td> <table width='100%' border=0> <tr> <!-- the menu --> <td id=\"@@MENUID@@\" valign='top' width='90%'> </td> </tr> <tr> <td> <p>&nbsp;<br> <!-- the generated page --> <h1>@@HEADER@@</h1> @@DATA@@ </td> </tr> </table> </td> <!-- the right hand image --> <td width=10 align='right' valign='top'></td> </tr> </table> </body> </html> ">>. �������������������������������yaws-2.0.2/applications/wiki/src/wiki_diff.erl������������������������������������������������������0000664�0001750�0001750�00000004741�12605311412�016301� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-module(wiki_diff). %% File : diff.erl %% Author : Joe Armstrong (joe@bluetail.com) %% Purpose : Diff of two files (like Diff and patch). %% diff(New, Old) -> Patch %% patch(New, Patch) -> Old %% patchL(New, [Patch]) -> Old' %% -compile(export_all). -export([diff/2, diff_files/2, patch/2, patchL/2]). -export([test/0]). -import(lists, [foldl/3, reverse/1]). test() -> diff_files("diff.erl", "diff.erl.old"). diff_files(F1, F2) -> {ok, B1} = file:read_file(F1), {ok, B2} = file:read_file(F2), diff(binary_to_list(B1), binary_to_list(B2)). diff(New, Old) -> Patch = diff(str2lines(Old), str2lines(New), []), %% io:format("Patch size=~p~n",[size(Patch)]), check(Patch, New, Old), Patch. check(Patch, New, Old) -> case patch(New, Patch) of Old -> true; _ -> exit(oops) end. patchL(New, Patches) -> foldl(fun(Patch, N) -> patch(N, Patch) end, New, Patches). patch(New, Patch) -> sneaky_flatten(patch1(binary_to_term(Patch), str2lines(New))). patch1([{L1,L2}|T], New) -> [get_lines(L1, L2, New)|patch1(T, New)]; patch1([H|T], New) -> [H|patch1(T, New)]; patch1([], _) -> []. get_lines(_, L2, [{L2,S}|_]) -> S; get_lines(L1, L2, [{L1,S}|T]) -> [S|get_lines(L1+1, L2, T)]; get_lines(L1, L2, [_|T]) -> get_lines(L1, L2, T). sneaky_flatten(L) -> binary_to_list(list_to_binary(L)). diff([], _, Patch) -> term_to_binary(reverse(Patch)); diff(Old = [{_,Str}|T], New, Patch) -> case match(Old, New) of {yes, Ln, Ln, Old1} -> case Str of "\n" -> diff(Old1, New, [Str|Patch]); _ -> diff(Old1, New, [{Ln,Ln}|Patch]) end; {yes, L1, L2, Old1} -> diff(Old1, New, [{L1,L2}|Patch]); no -> diff(T, New, [Str|Patch]) end. match([{_Ln,Str}|T], [{L1,Str}|T1]) -> extend_match(T, T1, L1, L1); match(X, [_|T]) -> match(X, T); match(_X, []) -> no. extend_match([{_,S}|T1], [{L2,S}|T2], L1, _) -> extend_match(T1, T2, L1, L2); extend_match(X, _, L1, L2) -> {yes, L1, L2, X}. str2lines(L) -> str2lines(L, 1, [], []). str2lines([H|T], Line, C, L) -> case H of $\n -> str2lines(T, Line+1,[],[{Line,reverse([$\n|C])}|L]); _ -> str2lines(T, Line, [H|C], L) end; str2lines([], _Line, [], L) -> reverse(L); str2lines([], Line, C, L) -> reverse([{Line,reverse(C)}|L]). �������������������������������yaws-2.0.2/applications/wiki/src/wiki_plugin_backlinks.erl������������������������������������������0000664�0001750�0001750�00000001330�12605311412�020677� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%% File : wiki_plugin_backlinks.erl %%% Author : Mickael Remond <mickael.remond@erlang-fr.org> %%% Description : This plugin can show the list of backlinks inline %%% Created : 20 Oct 2003 by Mickael Remond %%% <mickael.remond@erlang-fr.org> -module(wiki_plugin_backlinks). -export([run/2]). run(Page, _ArgList) -> %% TODO: Fixme %% This is working if there is only one virtual server. %% A way to handle this cleanly is needed. {ok, _Gconf, [[Sconf|_Others]]} = yaws_api:getconf(), Root = yaws:sconf_docroot(Sconf), AllRefs = wiki_utils:getallrefs(Page, Root), lists:map(fun(F) -> [wiki_to_html:format_link(F, Root),"<br>"] end, AllRefs). ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/src/wiki_format_txt.erl������������������������������������������������0000664�0001750�0001750�00000047116�12605311412�017563� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-module(wiki_format_txt). %% File : wiki_format_txt.erl %% Author : Joe Armstrong (joe@bluetail.com) %% : Johan Bevemyr, minor modifications (jb@bevemyr.com) %% Purpose : Wiki formatting engine %% %% Rules: %% Inline annotations: %% * Bold %% '' Italic %% ''' Code %% ~[a-zA-Z1-9]+ Wiki link %% http://... URL %% %% Blocks (denoted by special characters in column 1): %% [ Note %% ... %% ] %% [expires:Date expire tagged region %% ... %% ] %% { Preformatted %% ... %% } %% {{ Embedded HTML %% ... %% }} %% < Writable region within a %% ... locked page %% > %% << Write append region within %% ... a locked page %% >> %% %% Bullets: (Column1) %% %% - * Text Then - in column1 is the tab %% level. The number of tabs = %% the number of -'s %% * is the bullet. Then the text %% - [Header] Text Is a displayed list. %% %% Blanks or tabs between the - mark %% and the * (or Header) and Text %% are not significant. -export([format/3, collect_wiki_link/1]). -compile(export_all). -import(lists, [member/2, map/2, reverse/1, reverse/2]). -record(env, {node, f, f1 = false, f2 = false, f3 = false, h1 = false, h2 = false, h3 = false, u = false, n = 0, dl = false }). format(Str, F, Node) -> Env = #env{node=Node,f=F}, Str1 = case Str of [$\n|_] -> Str; _ -> [$\n|Str] end, {_Env1, Txt} = format_txt(Str1, Env, [], Str1), Txt. blank_line(S=[$\n|_]) -> {yes, S}; blank_line([$\t|T]) -> blank_line(T); blank_line([$ |T]) -> blank_line(T); blank_line(_) -> no. format_txt([$\n|T], Env, L, Doc) -> case blank_line(T) of {yes, T1} -> {Env1, L1} = clear_line(Env, reverse("<p>\n", L)), format_txt(T1, Env1, L1, Doc); no -> after_nl(T, Env, [$\n|L], Doc) end; format_txt([$\\,H|T], Env, L, Doc) -> format_txt(T, Env, [H|L], Doc); format_txt([$*|T], Env, L, Doc) -> {Env1, L1} = char_style(b, Env, L), format_txt(T, Env1, L1, Doc); format_txt([$_|T], Env, L, Doc) -> {Env1, L1} = char_style(u, Env, L), format_txt(T, Env1, L1, Doc); format_txt([$=,$=,$=,$=|T], Env, L, Doc) -> {Env1, L1} = char_style(h1, Env, L), format_txt(T, Env1, L1, Doc); format_txt([$=,$=,$=|T], Env, L, Doc) -> {Env1, L1} = char_style(h2, Env, L), format_txt(T, Env1, L1, Doc); format_txt([$=,$=|T], Env, L, Doc) -> {Env1, L1} = char_style(h3, Env, L), format_txt(T, Env1, L1, Doc); %format_txt([${,${|T], Env, L, Doc) -> % emb(T,Env,L, Doc); format_txt("'''" ++ T, Env, L, Doc) -> {Env1, L1} = char_style(tt, Env, L), format_txt(T, Env1, L1, Doc); format_txt("''" ++ T, Env, L, Doc) -> {Env1, L1} = char_style(i, Env, L), format_txt(T, Env1, L1, Doc); format_txt("~" ++ T, Env, L, Doc) -> {Word, T1} = collect_wiki_link(T), Link = format_wiki_word(Word, Env), format_txt(T1, Env, reverse(Link, L), Doc); format_txt("http://" ++ T, Env, L, Doc) -> {Url, T1} = collect_url(T, []), Txt = format_external_url(Url), format_txt(T1, Env, reverse(Txt, L), Doc); format_txt("https://" ++ T, Env, L, Doc) -> {Url, T1} = collect_url(T, []), Txt = format_external_url(Url, "https://"), format_txt(T1, Env, reverse(Txt, L), Doc); format_txt("ftp://" ++ T, Env, L, Doc) -> {Url, T1} = collect_url(T, []), Txt = format_external_url(Url, "ftp://"), format_txt(T1, Env, reverse(Txt, L), Doc); format_txt("slideshow:" ++ T, Env, L, Doc) -> {X, T1} = collect_wiki_link(T), Txt = "<a href='slideShow.yaws?node="++wiki:str2urlencoded(Env#env.node)++ "&next=1'>"++yaws_api:htmlize(X)++ "</a>", format_txt(T1, Env, reverse(Txt, L), Doc); format_txt("mailto:" ++ T, Env, L, Doc) -> {X, T1} = collect_mail(T, []), Txt = "<a href='mailto:" ++ wiki:str2urlencoded(X) ++ "'>" ++ "<img border=0 src='WikiPreferences.files/mailto.png'>" ++ yaws_api:htmlize(X) ++ "</a>", format_txt(T1, Env, reverse(Txt, L), Doc); format_txt("mailtoall:" ++ T, Env, L, Doc) -> {Name, T1} = collect_wiki_link(T), case get_mailto(Doc, []) of [] -> format_txt(T, Env, L, Doc); [F|Rs] -> Recipients = [F | [[$,|R] || R <- Rs]], Txt = "<a href='mailto:" ++ wiki:str2urlencoded(Recipients) ++ "'>" ++ yaws_api:htmlize(Name) ++ "</a>", format_txt(T1, Env, reverse(Txt, L), Doc) end; format_txt("<?plugin " ++ T, Env, L, Doc) -> Page = Env#env.node, {Txt, T1} = plugin(T, Page), format_txt(T1, Env, reverse(Txt, L), Doc); format_txt([H|T], Env, L, Doc) -> format_txt(T, Env, reverse(yaws_api:htmlize([H]))++L, Doc); format_txt([], Env, L, _Doc) -> {_, L1} = clear_line(Env, L), {Env, reverse(L1)}. format_wiki_word(Str, Env) -> F = Env#env.f, F({wikiLink, Str}). collect_url(S=[$ |_], L) -> {reverse(L), S}; collect_url(S=[$,|_], L) -> {reverse(L), S}; collect_url(S=[$)|_], L) -> {reverse(L), S}; collect_url(S=[$.,$ |_], L) -> {reverse(L), S}; collect_url(S=[$.,$\n|_], L) -> {reverse(L), S}; collect_url(S=[$.,$\r|_], L) -> {reverse(L), S}; collect_url(S=[$.,$\t|_], L) -> {reverse(L), S}; collect_url(S=[$\n|_], L) -> {reverse(L), S}; collect_url([H|T], L) -> collect_url(T, [H|L]); collect_url([], L) -> {reverse(L), []}. collect_mail(S=[$ |_], L) -> {reverse(L), S}; collect_mail(S=[$)|_], L) -> {reverse(L), S}; collect_mail(S=[$<|_], L) -> {reverse(L), S}; collect_mail(S=[$>|_], L) -> {reverse(L), S}; collect_mail(S=[$.,$ |_], L) -> {reverse(L), S}; collect_mail(S=[$.,$\n|_], L) -> {reverse(L), S}; collect_mail(S=[$.,$\r|_], L) -> {reverse(L), S}; collect_mail(S=[$.,$\t|_], L) -> {reverse(L), S}; collect_mail(S=[$\n|_], L) -> {reverse(L), S}; collect_mail([H|T], L) -> collect_mail(T, [H|L]); collect_mail([], L) -> {reverse(L), []}. get_mailto([$\\,_C|T], L) -> get_mailto(T, L); get_mailto("mailto:"++T, L) -> {Link, T1} = collect_mail(T, []), get_mailto(T1, [Link|L]); get_mailto([_|T], L) -> get_mailto(T, L); get_mailto([], L) -> L. format_url(Url, {_,_,_,F}) -> F(Url). format_external_url(F) -> format_external_url(F, "http://"). format_external_url(F, Scheme) -> F1 = Scheme ++ F, case is_graphic(F) of true -> "<img src=\"" ++ wiki:str2urlencoded(F1) ++ "\">"; false -> "<a href=\"" ++ wiki:str2urlencoded(F1) ++ "\">" ++ "<img border=0 src='WikiPreferences.files/http.png'>" ++ yaws_api:htmlize(F1) ++ "</a> " end. is_graphic(F) -> member(filename:extension(F), [".gif", ".GIF", ".jpg", ".JPG"]). after_nl([${,$\n|T], Env, L, Doc) -> pre(T, Env, L, Doc); %after_nl([${,${|T], Env, L, Doc) -> emb(T, Env, L, Doc); after_nl([${|T], Env, L, Doc) -> pre(T, Env, L, Doc); after_nl("[expires:"++T, Env, L, Doc) -> eregion(T, Env, L, Doc); after_nl([$[|T], Env, L, Doc) -> note(T, Env, L, Doc); after_nl("____" ++ T, Env, L, Doc) -> hr(T, Env, L, Doc); after_nl(S=[$-|_T], Env, L, Doc) -> mk_list(S, Env, L, Doc); after_nl(T, Env, L, Doc) -> format_txt(T, Env, L, Doc). hr(T, Env, L, Doc) -> {Env1, L1} = clear_line(Env, L), L2 = reverse("<hr>\n", L1), format_txt(T, Env1, L2, Doc). pre(T, Env, L, Doc) -> {Env1, L1} = clear_line(Env, L), L2 = reverse("<pre>\n", L1), pre1(T, Env1, L2, Doc). pre1([$\r,$}|T], Env, L, Doc) -> L1 = reverse("\n</pre>\n", L), format_txt(T, Env, L1, Doc); pre1([$\n,$}|T], Env, L, Doc) -> L1 = reverse("\n</pre>\n", L), format_txt(T, Env, L1, Doc); pre1([$<|T], Env, L, Doc) -> L1 = reverse("&lt;", L), pre1(T, Env, L1, Doc); pre1([$>|T], Env, L, Doc) -> L1 = reverse("&gt;", L), pre1(T, Env, L1, Doc); pre1([H|T], Env, L, Doc) -> pre1(T, Env, [H|L], Doc); pre1([], Env, L, Doc) -> pre1([$\n,$}], Env, L, Doc). emb([$},$}|T], Env, L, Doc) -> format_txt(T, Env, L, Doc); emb([H|T], Env, L, Doc) -> emb(T, Env, [H|L], Doc); emb([], Env, L, Doc) -> emb([$},$}], Env, L, Doc). eregion(T0, Env, L, Doc) -> {DateStr,T1} = collect_wiki_link(T0), Date = parse_date(DateStr), Expired = date_less(Date, {date(),time()}), {Region, T2} = collect_region($], T1, []), case Expired of error -> L1 = reverse("ERROR: bad expires date entry - "++DateStr++". " "The date should be on the form \"3 Jan 2003 " "00:00:00\".", L), format_txt(T2, Env, L1, Doc); true -> format_txt(T2, Env, L, Doc); false -> {Env1, RTxt} = format_txt(Region, Env, [], Doc), L1 = reverse(RTxt, L), format_txt(T2, Env1, L1, Doc) end. collect_region(_, [], Acc) -> {lists:reverse(Acc), []}; collect_region(End, [$\n,End|T], Acc) -> {lists:reverse(Acc), T}; collect_region(End, [C|T], Acc) -> collect_region(End, T, [C|Acc]). date_less(error,_) -> error; date_less(_,error) -> error; date_less(D1,D2) -> Ds1 = calendar:datetime_to_gregorian_seconds(D1), Ds2 = calendar:datetime_to_gregorian_seconds(D2), Ds1 < Ds2. -record(date, { year, month, day, hours, minutes, seconds }). parse_date(Date) -> parse_date(Date, #date{}). parse_date([], D) -> Entries = tl(tuple_to_list(D)), AllDone = lists:all(fun(X) -> if is_integer(X) -> true; true -> false end end, Entries), if AllDone -> {{D#date.year,D#date.month,D#date.day}, {D#date.hours,D#date.minutes,D#date.seconds}}; true -> error end; parse_date([D|Ds], Date) -> case char_type(D) of space -> parse_date(Ds, Date); alpha when Date#date.month == undefined -> case is_month(lowercase([D|Ds])) of false -> parse_date(Ds, Date); {true, M, Rest} -> parse_date(Rest, Date#date{month=M}) end; alpha -> parse_date(Ds, Date); digit -> case parse_time([D|Ds]) of error -> {Number,Rest} = get_number([D|Ds], 0), if Number < 32, Date#date.day == undefined -> parse_date(Rest, Date#date{day=Number}); Number < 50, Date#date.year == undefined -> parse_date(Rest, Date#date{year=Number+2000}); Number < 100, Date#date.year == undefined -> parse_date(Rest, Date#date{year=Number+1900}); Number > 1900, Date#date.year == undefined -> parse_date(Rest, Date#date{year=Number}); true -> parse_date(Rest, Date) end; {Hours, Minutes, Seconds, Rest} -> parse_date(Rest, Date#date{hours=Hours, minutes=Minutes, seconds=Seconds}) end; _ -> parse_date(Ds, Date) end. lowercase([C|S]) -> [lowercase(C)|lowercase(S)]; lowercase(C) when C>=$A, C=<$Z -> C+32; lowercase(C) -> C. is_month("jan"++Rest) -> {true, 1, Rest}; is_month("feb"++Rest) -> {true, 2, Rest}; is_month("mar"++Rest) -> {true, 3, Rest}; is_month("apr"++Rest) -> {true, 4, Rest}; is_month("may"++Rest) -> {true, 5, Rest}; is_month("jun"++Rest) -> {true, 6, Rest}; is_month("jul"++Rest) -> {true, 7, Rest}; is_month("aug"++Rest) -> {true, 8, Rest}; is_month("sep"++Rest) -> {true, 9, Rest}; is_month("oct"++Rest) -> {true, 10, Rest}; is_month("nov"++Rest) -> {true, 11, Rest}; is_month("dec"++Rest) -> {true, 12, Rest}; is_month(_) -> false. enc_month(1) -> "Jan"; enc_month(2) -> "Feb"; enc_month(3) -> "Mar"; enc_month(4) -> "Apr"; enc_month(5) -> "May"; enc_month(6) -> "Jun"; enc_month(7) -> "Jul"; enc_month(8) -> "Aug"; enc_month(9) -> "Sep"; enc_month(10) -> "Oct"; enc_month(11) -> "Nov"; enc_month(12) -> "Dec". enc_day(1) -> "Mon"; enc_day(2) -> "Tue"; enc_day(3) -> "Wed"; enc_day(4) -> "Thu"; enc_day(5) -> "Fri"; enc_day(6) -> "Sat"; enc_day(7) -> "Sun". char_type(D) when D>=$a, D=<$z -> alpha; char_type(D) when D>=$A, D=<$Z -> alpha; char_type(D) when D>=$0, D=<$9 -> digit; char_type($\ ) -> space; char_type($\n) -> space; char_type($\t) -> space; char_type($\v) -> space; char_type(_) -> unknown. get_number([D|Ds], N) when D>=$0, D=<$9 -> get_number(Ds, N*10+(D-$0)); get_number(Rest, N) -> {N, Rest}. parse_time(Time) -> F = fun() -> {Hour,[$:|R1]} = get_number(Time, 0), {Minutes,[$:|R2]} = get_number(R1, 0), {Seconds,R3} = get_number(R2, 0), {Hour, Minutes, Seconds, R3} end, case catch F() of {Hour, Minutes, Seconds, Rest} when is_integer(Hour), is_integer(Minutes), is_integer(Seconds) -> {Hour, Minutes, Seconds, Rest}; _ -> error end. note(T, Env, L, Doc) -> {Env1, L1} = clear_line(Env, L), L2 = reverse(note_start(), L1), note1(T, Env1, L2, Doc). note1([$\n,$]|T], Env, L, Doc) -> L1 = reverse(note_end(), L), format_txt(T, Env, L1, Doc); note1([H|T], Env, L, Doc) -> note1(T, Env, [H|L], Doc); note1([], Env, L, Doc) -> note1([$\n,$]], Env, L, Doc). note_start() -> "<p><table cellpadding=20> <tr><td width=\"75%\"></td> <td bgcolor=\"yellow\"><font size=\"-1\">". note_end() -> "</font></td></tr></table><p>\n". mk_list(T, Env, L, Doc) -> {Lev, T1} = count_indent_levels(T, 0), {Env1, L1} = adjust_indents(Env, Lev, L), T2 = skip_blanks(T1), case T2 of [$*|T3] -> format_txt(T3,Env1,reverse("<li>", L1), Doc); [$[|T4] -> {Env2, L2} = open_dl(Env1, L1), add_dl(T4, Env2, reverse("<dt>", L2), Doc); _ -> format_txt(T2,Env1,L1, Doc) end. skip_blanks([$ |T]) -> skip_blanks(T); skip_blanks([$\n|T]) -> skip_blanks(T); skip_blanks([$\t|T]) -> skip_blanks(T); skip_blanks(X) -> X. open_dl(Env, L) when Env#env.dl == false -> {Env#env{dl=true}, reverse("<dl>", L)}; open_dl(Env, L) -> {Env, L}. add_dl([$]|T], Env, L, Doc) -> format_txt(T, Env, reverse("</dt><dd>", L), Doc); add_dl([$\n|T], Env, L, Doc) -> format_txt(T, Env, reverse("</dt><dd>", L), Doc); add_dl([H|T], Env, L, Doc) -> add_dl(T, Env, [H|L], Doc); add_dl([], Env, L, Doc) -> format_txt([], Env, reverse("</dt>", L), Doc). count_indent_levels([$-|T], N) -> count_indent_levels(T, N+1); count_indent_levels(T, N) -> {N, T}. adjust_indents(Env, K, L) when Env#env.n == K -> {Env, L}; adjust_indents(Env, K, L) when Env#env.n > K -> adjust_indents(Env#env{n=Env#env.n-1}, K, reverse("</ul>", L)); adjust_indents(Env, K, L) when K > Env#env.n -> adjust_indents(Env#env{n=Env#env.n+1}, K, reverse("<ul>", L)). clear_line(Env, L) when Env#env.f1==true -> clear_line(Env#env{f1=false}, reverse("</b>", L)); clear_line(Env, L) when Env#env.f2==true -> clear_line(Env#env{f2=false}, reverse("</i>", L)); clear_line(Env, L) when Env#env.f3==true -> clear_line(Env#env{f3=false}, reverse("</tt>", L)); clear_line(Env, L) when Env#env.dl==true-> clear_line(Env#env{dl=false}, reverse("</dl>", L)); clear_line(Env, L) when Env#env.n /= 0 -> {Env1, L1} = adjust_indents(Env,0,L), clear_line(Env1, L1); clear_line(Env, L) -> {Env, L}. char_style(u, Env, L) when Env#env.u == false -> {Env#env{u=true},reverse("<u>", L)}; char_style(u, Env, L) when Env#env.u == true -> {Env#env{u=false},reverse("</u>", L)}; char_style(b, Env, L) when Env#env.f1 == false -> {Env#env{f1=true},reverse("<b>", L)}; char_style(b, Env, L) when Env#env.f1 == true -> {Env#env{f1=false},reverse("</b>", L)}; char_style(i, Env, L) when Env#env.f2 == false -> {Env#env{f2=true},reverse("<i>", L)}; char_style(i, Env, L) when Env#env.f2 == true -> {Env#env{f2=false},reverse("</i>", L)}; char_style(tt, Env, L) when Env#env.f3==false -> {Env#env{f3=true},reverse("<tt>", L)}; char_style(tt, Env, L) when Env#env.f3==true -> {Env#env{f3=false},reverse("</tt>", L)}; char_style(h1, Env, L) when Env#env.h1==true -> {Env#env{h1=false},reverse("</h1>", L)}; char_style(h2, Env, L) when Env#env.h2==true -> {Env#env{h2=false},reverse("</h2>", L)}; char_style(h3, Env, L) when Env#env.h3==true -> {Env#env{h3=false},reverse("</h3>", L)}; char_style(h1, Env, L) when Env#env.h1==false -> {Env#env{h1=true},reverse("<h1>", L)}; char_style(h2, Env, L) when Env#env.h2==false -> {Env#env{h2=true},reverse("<h2>", L)}; char_style(h3, Env, L) when Env#env.h3==false -> {Env#env{h3=true},reverse("<h3>", L)}. collect_wiki_link([$"|X]) -> collect_wiki_link(X, [], true); collect_wiki_link(X) -> collect_wiki_link(X, [], false). collect_wiki_link([$"|T], L, true) -> {reverse(L), T}; collect_wiki_link([Any|T], L, true) -> collect_wiki_link(T, [Any|L], true); collect_wiki_link([H|T], L, Quoted) when $A =< H, H =< $Z -> collect_wiki_link(T, [H|L], Quoted); collect_wiki_link([H|T], L, Quoted) when $a =< H, H =< $z -> collect_wiki_link(T, [H|L], Quoted); collect_wiki_link([H|T], L, Quoted) when $0 =< H, H =< $9 -> collect_wiki_link(T, [H|L], Quoted); collect_wiki_link(S=[H|T], L, Quoted) -> case member(H, "äÄöÖåÅ") of true -> collect_wiki_link(T, [H|L], Quoted); false -> {reverse(L), S} end; collect_wiki_link(T, L, _Quoted) -> {reverse(L), T}. %% Plugin implementation. %% The plugin is a special syntaxe in Wiki pages: %% <?plugin name arg1=Value1 ... ?> %% When such a syntax is used, the following function is called: %% wiki_plugin_name:run([{arg1, Value1}, ...]). plugin(Data, Page) -> case string:str(Data, "?>") of 0 -> %% Broken plugin syntax {"", "<?plugin " ++ Data}; EndPluginIndex -> PluginData = string:sub_string(Data, 1, EndPluginIndex -1), [PluginName| ArgStrings] = string:tokens(PluginData, " "), Result = exec_plugin(PluginName, Page, ArgStrings), Rest = string:sub_string(Data, EndPluginIndex + 2), {Result, Rest} end. exec_plugin(Name, Page, ArgStrings) -> exec_plugin(Name, Page, ArgStrings, []). exec_plugin(Name, Page, [], ArgsList) -> case catch apply(list_to_atom("wiki_plugin_" ++ Name),run, [Page, ArgsList]) of {'EXIT', Reason} -> io_lib:format("Plugin error: ~p", [Reason]); Result -> Result end; exec_plugin(Name, Page, [ArgString|ArgStrings], Acc) -> [Key,Val] = string:tokens(ArgString, "="), exec_plugin(Name, Page, ArgStrings, [{Key,Val}|Acc]). ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/src/wiki_plugin_menu.erl�����������������������������������������������0000664�0001750�0001750�00000002604�12605311412�017707� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-module(wiki_plugin_menu). %%% File : wiki_plugin_menu.erl %%% Author : Mickal Remond <mickael.remond@erlang-fr.org> %%% Description : Allows the selection and display of a menu Links are %%% selected base on first word of the page name (Menu, %%% Category, ...). The other part of the title is the %%% name of the menu entry. %%% Created : 22 Oct 2003 by Mickael Remond %%% <mickael.remond@erlang-fr.org> -export([run/2]). run(_Page, ArgList) -> %% TODO: Fixme %% This is working if there is only one virtual server. %% A way to handle this cleanly is needed. {ok, _Gconf, [[Sconf|_Others]]} = yaws_api:getconf(), Root = yaws:sconf_docroot(Sconf), Prefix = get_prefix(ArgList), %% Get all page starting with a given word Pages = wiki_utils:getpages_by_prefix(Prefix, Root), lists:map(fun(F) -> [wiki_to_html:format_menu_link(Prefix, F, Root),"<br>"] end, Pages). %% Get the category to use in the menu If not passed as parameter, use %% "Category" %% Be careful: plugin syntax is for the moment case sensitive get_prefix(ArgList) -> case lists:keysearch("prefix", 1, ArgList) of {value, {"prefix", Prefix}} -> Prefix; _Other -> "Category" end. %% TODO: is it relevant to be able to handle several category in %% the menu ? ����������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/src/wiki_yaws.erl������������������������������������������������������0000664�0001750�0001750�00000007314�12605311412�016353� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������% -*- Erlang -*- % File: wiki_yaws.erl (~jb/work/wiki/src/wiki_yaws.erl) % Author: Johan Bevemyr % Created: Thu Jun 27 22:26:49 2002 % Purpose: Yaws support utilities -module('wiki_yaws'). -author('jb@son.bevemyr.com'). -export([get_path_prefix/1, parse_multipost/1, parse_post/2, call_with_multi/3, call_with_query/3, call_with_post/3, call_wiki/3, call_with_multiquery/3]). -include("../../../include/yaws_api.hrl"). get_path_prefix(UrlPath) -> %% search for initial path part case string:rchr(UrlPath, $/) of 0 -> UrlPath; N -> lists:sublist(UrlPath, N) end. parse_multipost(Arg) -> case yaws_api:parse_multipart_post(Arg) of {result, PostList} when Arg#arg.state == undefined-> {done, parse_post(PostList,[])}; {result, PostList} -> Params = Arg#arg.state++PostList, {done, parse_post(Params,[])}; {cont, Cont, Res} when Arg#arg.state == undefined -> {get_more, Cont, Res}; {cont, Cont, Res} -> {get_more, Cont, Arg#arg.state ++ Res} end. parse_post([], Acc) -> Acc; parse_post([{head, {Name, Opts}}|Rest], Acc) -> parse_post(Rest, [{to_string(Name), "", Opts}|Acc]); parse_post([{body, Data}|Rest], [{Name, Value, Opts}|Acc]) -> parse_post(Rest, [{to_string(Name), Value++Data, Opts}|Acc]); parse_post([{part_body, Data}|Rest], [{Name, Value, Opts}|Acc]) -> parse_post(Rest, [{to_string(Name), Value++Data, Opts}|Acc]); parse_post([{Name, Value}|Rest], Acc) -> parse_post(Rest, [{to_string(Name), Value, []}|Acc]). to_string(Atom) when is_atom(Atom) -> atom_to_list(Atom); to_string(String) -> String. call_with_multi(M, F, Arg) -> case parse_multipost(Arg) of {done, Params} -> WikiRoot = filename:dirname(Arg#arg.fullpath), {abs_path, P} = (Arg#arg.req)#http_request.path, Path = yaws_api:url_decode(P), Prefix = wiki_yaws:get_path_prefix(Path), M:F(Params, WikiRoot, Prefix); {get_more, Cont, State} -> {get_more, Cont, State} end. call_with_multiquery(M, F, Arg) -> case parse_multipost(Arg) of {done, Params} -> WikiRoot = filename:dirname(Arg#arg.fullpath), {abs_path, P} = (Arg#arg.req)#http_request.path, Path = yaws_api:url_decode(P), Prefix = wiki_yaws:get_path_prefix(Path), QueryArgs = yaws_api:parse_query(Arg), QParams = [{N,V,[]} || {N,V} <- QueryArgs], M:F(QParams++Params, WikiRoot, Prefix); {get_more, Cont, State} -> {get_more, Cont, State} end. call_with_post(M, F, Arg) -> QueryArgs = yaws_api:parse_post(Arg), Params = [{N,V,[]} || {N,V} <- QueryArgs], WikiRoot = filename:dirname(Arg#arg.fullpath), {abs_path, P} = (Arg#arg.req)#http_request.path, Path = yaws_api:url_decode(P), Prefix = wiki_yaws:get_path_prefix(Path), M:F(Params, WikiRoot, Prefix). call_with_query(M, F, Arg) -> QueryArgs = yaws_api:parse_query(Arg), Params = [{N,V,[]} || {N,V} <- QueryArgs], WikiRoot = filename:dirname(Arg#arg.fullpath), {abs_path, P} = (Arg#arg.req)#http_request.path, Path = yaws_api:url_decode(P), Prefix = wiki_yaws:get_path_prefix(Path), M:F(Params, WikiRoot, Prefix). call_wiki(M, F, Arg) -> WikiRoot = filename:dirname(Arg#arg.fullpath), {abs_path, P} = (Arg#arg.req)#http_request.path, Path = yaws_api:url_decode(P), Prefix = wiki_yaws:get_path_prefix(Path), M:F([], WikiRoot, Prefix). ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/src/Makefile.am��������������������������������������������������������0000664�0001750�0001750�00000001467�12605311412�015700� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include @top_srcdir@/include.mk MODULES = utils.erl \ wiki_diff.erl \ wiki.erl \ wiki_format_txt.erl \ wiki_plugin_backlinks.erl \ wiki_plugin_dummy.erl \ wiki_plugin_menu.erl \ wiki_split.erl \ wiki_templates.erl \ wiki_to_html.erl \ wiki_utils.erl \ wiki_yaws.erl EXTRA_DIST = $(MODULES) EBIN_DIR=@builddir@/../ebin EBIN_FILES=$(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) clean-local: $(AM_V_at)rm -f $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/�������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�013751� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/storeTagged.yaws���������������������������������������������������0000664�0001750�0001750�00000000254�12605311412�017047� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = storeTagged, wiki_yaws:call_with_multi(wiki, F, Arg). </erl> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/changePassword2.yaws�����������������������������������������������0000664�0001750�0001750�00000000265�12605311412�017633� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = changePassword2, wiki_yaws:call_with_multiquery(wiki, F, Arg). </erl> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/slideShow.yaws�����������������������������������������������������0000664�0001750�0001750�00000000253�12605311412�016537� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = slideShow, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/editFiles.yaws�����������������������������������������������������0000664�0001750�0001750�00000000252�12605311412�016505� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = editFiles, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/lastEdited.yaws����������������������������������������������������0000664�0001750�0001750�00000000245�12605311412�016661� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = lastEdited, wiki_yaws:call_wiki(wiki, F, Arg). </erl> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/previewPage.yaws���������������������������������������������������0000664�0001750�0001750�00000000261�12605311412�017053� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = previewPage, wiki_yaws:call_with_multiquery(wiki, F, Arg). </erl> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/changePassword.yaws������������������������������������������������0000664�0001750�0001750�00000000257�12605311412�017552� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = changePassword, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/createNewPage.yaws�������������������������������������������������0000664�0001750�0001750�00000000256�12605311412�017313� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = createNewPage, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/editTag.yaws�������������������������������������������������������0000664�0001750�0001750�00000000250�12605311412�016154� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = editTag, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/copyFiles.yaws�����������������������������������������������������0000664�0001750�0001750�00000000253�12605311412�016533� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = copyFiles, wiki_yaws:call_with_multi(wiki, F, Arg). </erl> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/searchPage.yaws����������������������������������������������������0000664�0001750�0001750�00000000720�12605311412�016637� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = searchPages, if Arg#arg.clidata /= undefined -> %% io:format("post~n"), wiki_yaws:call_with_post(wiki, F, Arg); length(Arg#arg.querydata) > 0 -> %% io:format("query~n"), wiki_yaws:call_with_query(wiki, F, Arg); true -> wiki_yaws:call_wiki(wiki, F, Arg) end. </erl> </html> ������������������������������������������������yaws-2.0.2/applications/wiki/www/previewTagged.yaws�������������������������������������������������0000664�0001750�0001750�00000000256�12605311412�017376� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = previewTagged, wiki_yaws:call_with_multi(wiki, F, Arg). </erl> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/addFile.yaws�������������������������������������������������������0000664�0001750�0001750�00000000515�12605311412�016127� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> WikiRoot = filename:dirname(Arg#arg.fullpath), {abs_path, P} = (Arg#arg.req)#http_request.path, Path = yaws_api:url_decode(P), Prefix = wiki_yaws:get_path_prefix(Path), wiki:addFile(Arg, WikiRoot, Prefix). </erl> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.wob������������������������������������������������0000664�0001750�0001750�00000002042�12605311412�017465� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ƒhd�wik002k�ForgetMejhhb��Óa aha a ak�unknownk�tThis page contains the icons and styles used by the Wiki. To change an icon just replace the appropriate file below.l���hd�filek� template.htmljjhd�filek�template_info.htmljjhd�filek�url.pngk�Generic link iconjhd�filek� mailto.pngk�Mail link iconjhd�filek� interwiki.pngk�Interwiki link iconjhd�filek� https.pngk�HTTPS link iconjhd�filek�http.pngk�HTTP link iconjhd�filek�ftp.pngk� FTP link iconjhd�filek� allpages.gifk�Toolbar icon - All Pagesjhd�filek� editfiles.gifk�Toolbar icon - Edit Filesjhd�filek�edit.gifk�Button for inpage tag editingjhd�filek� editme.gifk�Toolbar icon - Edit Mejhd�filek� history.gifk�Toolbar icon - Historyjhd�filek�home.gifk�Toolbar icon - Homejhd�filek�icon.gifk�Upper right side logo - Erlangjhd�filek�lastedited.gifk�Toolbar icon - Last Editjhd�filek� zombies.gifk�Toolbar icon - Zombiesjhd�filek� custom.cssk�Style Sheet for Wikijjl���hm���ƒl���k�Enter your text here jhhb��Òa ahaaa)k�unknownj����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/getThumb.yaws������������������������������������������������������0000664�0001750�0001750�00000000133�12605311412�016352� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(Arg) -> F = getThumb, wiki_yaws:call_with_query(wiki, F, Arg). </erl> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/importFiles.yaws���������������������������������������������������0000664�0001750�0001750�00000000253�12605311412�017073� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = fixupFiles, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/AnUnlockedPage.wob�������������������������������������������������0000664�0001750�0001750�00000000667�12605311412�017233� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ƒhd�wik001jjhhb��Ða ahaaak�joek�…This page is unlocked - note it has a green border. To edit this page click on the ''Edit this page'' link at the top of the page. l���hm���eƒl���haak�QTo edit this page click on the ''Edit this page'' button at the top of the page. k� jhhb��Ða ahaaak�joehm���Wƒl���haak�CTo edit this page click on the Edit button at the top of the page. k� jhhb��Ða ahaaa,k�joej�������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/storePage.yaws�����������������������������������������������������0000664�0001750�0001750�00000000255�12605311412�016531� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = storePage, wiki_yaws:call_with_multiquery(wiki, F, Arg). </erl> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/finalDeletePage.yaws�����������������������������������������������0000664�0001750�0001750�00000000260�12605311412�017605� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = finalDeletePage, wiki_yaws:call_with_multi(wiki, F, Arg). </erl> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/allPages.yaws������������������������������������������������������0000664�0001750�0001750�00000000243�12605311412�016325� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = allPages, wiki_yaws:call_wiki(wiki, F, Arg). </erl> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/getMidSize.yaws����������������������������������������������������0000664�0001750�0001750�00000000135�12605311412�016641� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(Arg) -> F = getMidSize, wiki_yaws:call_with_query(wiki, F, Arg). </erl> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/���������������������������������������������0000775�0001750�0001750�00000000000�12605311412�020137� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/lastedited.gif�������������������������������0000664�0001750�0001750�00000003271�12605311412�022673� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a0�+�÷ÿ�ÿÿÿ!!!)))111999BBBJJJRRRZZZccckkksss{{{„„„ŒŒŒ”””œœœ¥¥¥­­­µµµskk„{kskZ„{cÎÆ­½µœskRÎÆ¥ÎÆœ”ŒcÞÖ¥ÎÆ””ŒZïç­ÞÖœïç¥ÿ÷­ÞÖŒÿ÷œ÷÷ïÿÿ÷ççÞ­­¥œœ”ŒŒ„{{s÷÷çÿÿïsskççÖÆÆµccZRRJÿÿç÷÷ÞœœŒççÎÖÖ½ŒŒ{ÆÆ­ÿÿÞBB9÷÷Ö991ssc­­”ççÆœœ„11)ÿÿÖ÷÷ÎccRŒŒsçç½­­ŒRRBÿÿÎ÷÷ÆssZççµÿÿÆŒŒk­­„÷÷½ccJçç­BB1½½Œÿÿ½œœs÷÷µssR­­{ÿÿµ½½„RR9ÎÎŒ11!ssJ))99!BB!ZZ)cc)RR!{{1kk)œœ9ss)ŒŒ1¥¥9­­9B1R!)”R½ŒJµZJc9)B{R”ŒR­Z1ss9”½Z÷R1cœJÆkJ{1!9„Rœk9„­ZÖ„B¥Æc÷Îcÿ½ZïµRçsJ„¥ZÆÖsÿµZÞ9!BcJkJ)R9191)1���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ÀÀÀ!ù��ÿ�,����0�+�@ÿ�ÿ H° Aƒ ,8 ÁÁ‡ÿð³¨"£E‡ð8¢cÈP;X¤°‘BŒ "ªxÀ š!B áá£æ 6Ø(RóÈ…–a’`%ÄoÖ¤‰s†DXJh™šê F³jݺR’¤RzU@„�H:�AR€½‚- °,¯ÿð¶}»•‚Hz(.2¤(‘@‡*V¼Ãõá~èÈ9ðB…Špäø$GŒ7~à ÁƒGÑÆ¼IÃF † qâ„ÊœXñ ¥7‡-MD@-Á™ ά)ÃA„Ä#âx÷±$ hÕà6¥@¯ Àÿý'@Ò]IyÑsàø„ôÔ᣸âè'(¸³‡þ"E8¢H!…ÐáH"tÂÇ€0Àø tÀŠu´à6¬`Ù&±@eFøÏcØ�Z ?èS <ÜàâDÄ$„5ù ÄøÆ6Ôx“ ¸vÄIAG`@mµµÇÕqŒ‡WHáDTXaÅSxÑ›MxÑ-ˆøoL G?|á¦'„‘�VfÖ‰ßtFµEW\_U^áý£çŸè $�”e Á |B�ß¡‡—^_Ù©)j40¡ ~²È}›¤P|‚-2Hõ‘jfÿÐGèÈF˜Ø"ˆDbæ�´V”‡yBØŠÂ!w0A �H�]„¢Ø!^TGÈà€e*¸àBC¨àjt‰Ê«?°0C —©`à Ѐƒ‰7Ä „9"*à ï~¦CÈ  /¸D ? ábt×Ò.î�–Ã@Øpƒ=1�HøðCùC誑ÆÇH Ñ£`Ä><ñÃ4ÁÍN iDÄOºá†OÅFP1dUDÑD?0yEV’€Á¹[�‡m „Ná„Yü0À½…ÀAÚ?PfŽq ‘½M1�½™€ÅT^`–1§hÂ!eFˆ¡…¸)†  \jàj¸ÁÔ _ €…p¥4Á´ \e@㙇¾ž+IA^¥Nhzÿ˜î$ë†ÐÝ?”7€ëµGú™_áågî¨*У”uÖ[“F)ŸrUÊ:¦{òIPyÈ.) ¬©óÁ?Þö•6Ÿ½�HÒ@¶S*{ô©O—=Á–ºþ?�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/allpages.gif���������������������������������0000664�0001750�0001750�00000004024�12605311412�022336� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a0�+�÷ÿ�ÿÿÿ!!!111BBBJJJRRRZZZccckkksss{{{„„„ŒŒŒ”””œœœ¥¥¥­­­µµµ½½½ÆÆÆÎÎÎÞÞÞ÷÷÷kccZRRcZZRJJR91J91ZJBRB9cJ9ZB1sR9kJ1cB){R1sJ)ŒZ1¥k9„R)kZJsZBJ9){skZRJRJB91)1)!ZJ9{cJ½”kµŒckR9„cBcJ1{Z9ÖœcZB)”kBï­kΔZkJ)„Z1cB!{R)”c1­s9kcZJB9ÿÆ„ïµsç­kÆ”Zÿ½s¥{JÞ¥c„Z)µ”k­Œc¥„Zœ{R½”c”sJ­„RŒkB÷½sïµk½ŒRç­csR)Œc1kZBÿÖœ”{ZŒsR„kJÿÎŒ{cBÖ­s÷ƄΥkï½{sZ9Þ­kÿÆ{½”ZÖ¥ckR1µŒRΜZcJ)cR9½œkµ”c­ŒZÿ΄¥„Rï½sœ{JçµkÞ­cÿÖ””{RZJ1ç½{ŒsJRB)„kBÖ­kÿÎ{ÆœZÿÞ¥B9)œ„ZέsÿÖŒïÆ{ç½s­ŒR{c9¥„J„sRÿÞœ{kJscB¥ŒZkZ9”{JRJ9JB1¥ŒR{kBÿç¥ÿ÷ÞRJ1ÿï­kcBÖÎ¥ÿï¥{sJ÷ïœÿÿ÷ÞÞÖççÞ­­¥µµ­ÿÿïZZRµµ¥ccZRRJÿÿçJJBÿÿÞ÷÷ÖµµœÿÿÖZZJµµ”çç½ÿÿεµŒÿÿÆJJ9½½Œÿÿ½ssR­­{½½„ÿÿ­””c­­sÞÞ”JJ1½½{Î΄ÿÿœ””Z÷÷”µµkŒŒRÖÖ{÷÷Œ÷ÿ­Þ猵½kœ¥ZÆÎÎÎÖÖÖÞÞÞç甜œœ¥­ÆÎÖœ¥ÿZc­ZcµksÎksÖççïÖÖÞÞÞ眜¥ss{kksRRZZZcJJRRRcµµÿJJk­­ÿRR{¥¥ÿJJsœœÿZZ”JJ{RRŒZZœcc­„„猌÷{{ÞŒŒÿkkÆssÖssÞRJs91JZJZ���ÀÀÀ!ù��ÿ�,����0�+�@ÿ�ÿ (pA‚hÅŒ# @tÐF+ ªÌ @Á‚ < H²¤ÀWD*ñ1f€—0_º°‰E“š¦ Œ§>Cf˜*‰8TÖ¨Ù�³>vPÙÕ#wJ„ ,P GfŒ.B‰š¤ð!H%NÚ¤M»ÇIÚ6Jps6j˜±bÂz‘ÉbHX¢üù30Pð?Ã…00A¬c‚ü9øGÀß‚Ãþ0D<P?,C à9³ƒÈ ü[y€j“GT@ªi³¶íÛ6QQÕçŸ/“Pü},ð�‹ø€‘ö²>uQÙ©“—‰ëבØáóÕq‚Jÿ¨‚‡‘%zЯÐ÷Æ£,^lÁšE¬ZdÖÜòá;Á)tÄ€A Ð&Ø šà '�D9Äà˜?4àOÆf‚Iö4€df&Xiÿ�¼VRDøAƒ€ô"”DPI‡RHH}�"dtP þ t d|I"`„$\v Ƶ™!J3Ê$ƒŒ ›@òÄpÄq@DcDÒ6/‘RÁ œ“Î:ïðÈMhx1‰$bÌa"Cxe(ðPÆwDðR)íD']>bX‡Ý‹,b‡‰FùJlX’Çì•:ܘÿÃI*®Ôê )«à@ˆü‰:AC‘„j«†ƒ´‘žY¤±Ë-¹D›Ë-¸E~‰úÏ (¸¡Äà¶åV;»ÃK¤»ÃK°Á†wDÚÖk¯@øSYcš}h˜†ŒXY�¬¦¯C€Úd ´¦ZiŠu¨bf‰‘Ù•9¢fê€gÜ+V¾‚]V¯ ªðDCpq\H(³Ì%�!D3ó¢1 ›XiH$CÉÑHmˆ!qI%Dô%AÐP“•_d]Û|ÐfÓŸSŽ.Ä”aˆ&(@å+]°`e×|N5ÞÔí 8¬˜¦(;ÿ›„”¨(ÉÑõr1½„Á´<B…"+…Ì3Æ,3É&ˆ²ù˜q~˜ñŜ͵3=÷¸£Ž:ñb"c€y5¨Šú‡�øÖ/¡"tÑmSf„v á• ôF©@<œaG ÔIÎ=Pe•6‡L‘¤d¬ Gܹûw ˜�D‹àñA8$°{T÷ˆ)¤�€ŠŸž µÖè<IÀЀ=ôÃtô€Ç . X8ЮE~°µ¿ïH@\�DŠE,%à h‚’€b·Há-fQ­kõ*Jè„ Òµ¨Á 7Äaõ€_ä‚@äE.á~¡ƒ,ì§‚Ä¡À ‚pƒ=´á‰P|⸶`?L" dÀ z‡(á $ÐÜcTу0IdÐAnà6º!p„cx@ÇØQBÇÑÖ!‚øñ0ø�Zñ‚ !¬H@G>€8À°$ ²J~‡‚@Åü¥¯)À’©Œg 1Í$ÆðGÈRY€È(l0†�,5é" …LcðLÀúE1‰u„’#€�N¤±‰a†�ÈüN”š„¦� 8‘j6V±ÍøÄDM,gÙ"Ø”%)™?ð˜€��;ë 2MI’üÃ`à �;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/custom.css�����������������������������������0000664�0001750�0001750�00000000600�12605311412�022077� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������body, td { font-family : Verdana, Arial, sans-serif ; font-size : 9pt; } /* links without underline */ a { text-decoration: none; } /* visual link effect */ a:hover { text-decoration: underline; } TEXTAREA{ width : 100%; } #menu{ background: #BFEE90; } #lockedmenu{ background: #EF0000; } #lockedmenuframe { background: #FF1010; } #menuframe { background: #90EE91; } ��������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/kamera.gif�����������������������������������0000664�0001750�0001750�00000002407�12605311412�022011� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a �!�÷ÿ�ÿÿÿ!!!)))111999BBBJJJœ””Œ„„{ssskk„{{ÞÎÎçÖÖkccÖÆÆ½­­ÆµµÎ½½ZRRµ¥¥cZZRJJ­œœœŒŒ¥””ïÖÖJBB”„„ÞÆÆçÎÎÖ½½Œ{{嵄ssÆ­­{kkB99911sccµœœ¥ŒŒkZZ1))cRR)!!!��çÎÆÞÎÆ”Œ„kcZRRJ))!���RJRB9BkZcµ¥­œŒ””„Œ{kssckZJR¥”œ„s{cRZֽƵœ¥ÞÆÎ½¥­Îµ½���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������,���� �!�@ÿ�£H° Áƒ¨P!F ".¬ÂH "Žà !5@åÈ(.*ˆPÉR„ x$œ9°G4s´pâ  :™�QÄ` 4p(ÐYà@Š;¢ÀC@ È éá È‚žpø°`ƒ J04¨Á%$îh"À®ß ,$™P€ €\ p‚ PQÂH<*0yðbfnl€ò¸Å@–dðP€æŒ­1@pòXD&.+@ $ÀÁ­:4‰2£ÀV¢+“'wÒÀïÁ ˜PR×ùAYPj`J¬ìðݽ<Â�0ˆÐ:ŠPñ@CŒ™9B\@á"… l "Pp€@B@äD PPƒmPTð@.ܶ2b µà@ ð%…D=‚"|ÐY8áL)˜w#l@Ä L@‚J¶•P�Tpqcy�QK U x€ÁL<pCˆ0šAÉ&ôu$D€Pyqð�Fð˜‹"0fÔC†Á àé8P ÀÀ¦ îe`dž:ÀAô$hTÄ•æEPÁ¡Q ‘�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/editfiles.gif��������������������������������0000664�0001750�0001750�00000003016�12605311412�022516� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a0�+�÷ÿ�ÿÿÿ!!!)))111999BBBJJJRRRZZZkkksss{{{„„„ŒŒŒ”””œœœ¥¥¥­­­µµµÆÆÆÖÖÖççç÷÷÷B9)91!RBcRB9½œ!ïÆ)„s)µœ1RJ!¥”9ÿÞBŒ{!ÿÞ9½¥)scïÎ)sk9cZ!ÿçRÞÆ9ïÖ9ÞÆ1ε)sk1ÿçJZRÿçB­œ)œŒ!ïçœÎÆ{ÿïc”Œ9ÿïZÿïRÞÎBkcÿ÷”ÿ÷Œÿ÷„ÞÖcœ”1ÿ÷{ÿ÷sÿ÷kÿ÷cïçZÿ÷ZÎÆBÿÿ÷ÖÖÎÆÆ½ÿÿïkkcÖÖÆÿÿçJJBÿÿÞœœ„11)ÿÿÖÆÆ¥ÿÿÎÆÆœÿÿÆJJ9kkRÿÿ½99)çç¥ÿÿµ÷÷­ÿÿ­ÿÿ¥ŒŒZœœc­­kÿÿœ))99!ÿÿ”ÎÎsJJ)ÿÿŒÿÿ„ÎÎcÿÿ{ŒŒBÿÿs­­J���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ÀÀÀ!ù��ÿ�,����0�+�@ÿ�ÿ H°àÀ ü÷@A J”A‚9rѨшG#E@I’&ªüG¡À-X¸dÁ‚ÅŠM+SrN‰ÂÓ‰OŸK– XIt`C�H‘^h`@Á„¢*éH•J*ÕTJG Õ®E¹v]@§À€®Tÿ(;0m[´] # Â?sØ]Ù� €»¢pá,v(Þ1¤Ô‚b™,D˜œÙ|fŒç1bBƒ=:ŒÇ!@ŠàBÒ×°``à Ô¸s¯äñë?ªؾ•ñ7\ãd»ÐàÁÞ¢øø`‚‡ @q"0àCuÿ4ÐâpâÅ9v¤ÏÈ~cÇ4ºÙ$ñ(GÄ’ELꟈÿË™±ÆºEgbabFv¡Å„4Uxâ „�Q8!?%bl¯apZ†P�­‘€ àŠ+`#OѨãŽoDÖZ]ÑYhåX)öÖUs  yíå–qT'Ü‘ùFÕ>ð�Yð(&QÀUAhpG (¤´ã ‚ $ài”`‚w2ÖÁm(>ÐAž…j <,æ¨z9ô^† „€¤ìµ÷‘G!!¡¨1PÅ #(‘Ʀá7ùÁ_qÈâ‰ZH¬ªÃ&½ú_fšqö™8<¡›oœ¡Y›}Zh ’¡„ž˜›eŒvƒNH¡…7á”OQH‘á[ØtÅ:Ûaˆ".ñÚ¤ºµÅM<áâ½À€Ž <�@öÞ À°�¨spAÄ&È:&A D ›j(4ñÆwì1TÄ ¹Õ?\2t¥qBWò”QÑÁå¾s!àtùÖËXRu–Ìü³œt„iœ—vi×ÉR3\)ÿÓ@�tIY–ÈPË|\pì‹åÈ:ÓÁ³Ï�-ôÇE�;BÝñX�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/icon.gif�������������������������������������0000664�0001750�0001750�00000004102�12605311412�021473� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87an�`�õ�����33fÿÿÿ™�f3��33�3333f33fff33f3fff3fff™��™�3™3�™33™™™™™Ì™Ì™Ì��Ì�3Ì�fÌ3�Ì33Ì3fÌf3ÌffÌf™Ì™fÌ™™Ì™ÌÌÌ™ÌÌÌÿ™™ÿ™ÌÿÌÌÿÌÿÿÿÌ���������������������������������������������������������������������������,����n�`��þ@pH,ȤrÉl:Gt*­NIϬvËÜP¿V!Å1.“ÏcwKyDnõú™iTìø»^¨Ç—esM&"~d XƒJ"€‰yBRzSScŽH^xyvgœE™RcQ|dª­R§G$Q±»rµC$—°Â|¬“¿E$¹Rv¬hӾˊzhbV¢eËC&ÑÓÝÏ}w›àÁÙfÅyUc‚ê׬Òåãíõà©F‰z÷�A@¦~5 uŽ!Ã^êHètPaIÙaÕ4]ÓúéQ¦î¢3|òäó` ñrõi¦Z-/—D‘4c†¤þ:/Ç4™;wÒ-p"†´ä·ÇtƯÍd ;± i霔¬§Î47Šl?°:6í*ïÒîòó*í¨5¡­RÊJ³ñš³©ûxÊ%ãö&U;¯œùl) „ÇKŽL¹„ `!´#9ðÆÏàÚ¹ “Ì7Ш;á¸MZê×sL˜D)�±°s7ùDEˆí\vu _ÂAÞ;²6‡+/‚sIªh—+1ÅΦg¢KÎN”ƒmwoÏ^.Üã•‹ëv\ÏÓôãÅîPÐNpøË«ß16 ÿø ß‘vÆ}þéæR6°Uæ&O‚¤AÓh"`€fVᆸþp¨a‡""#–Hâ‰#ž¨¢ˆ´oz0øKq Õè8Þ¨#Žæ((c-I &$LCòäÇ‘èL²#{óÞFÔyäâ^¼PIL•XB3 €E½sAŒ } ÍT¬`bÅ<ªHSš,lf©Ùèµ h¼…d•’aó%èèùGž˜°WŽ^üxJ Ö'îiÎ>V‘“ù”¥ z …Ó›�ª éa Æ¥NZ0gV¡j«:Ðê3Dƪh9ec‘Ú=²•TeIEU¥m)%°N)OûÁ#M®ƒ˜ÐÑL¿vÆOx ‹–4•Öé(tuFrËàÂ$¯ÛŠ&©”þŸ~ ¬YˆÕ6•¡Ð¨©¹€:k¨£Ru®,ØÝi-#¤k,°‘6…¯¨µ®"èh¢–ç¤2Aóé¦×§eN£+,}Vç˜ûJü&]ûbâKÛM¿vˆ‡ÔR„1Æ×ú*eÂúRð ”«R2 Ôîg¸TÚiÊÙjYÕ´gˆGBsSÕ§õõ×Õ*OÉiÍeËǵvk^(ÿÖâjPSñ¦ ë.0Í JR‹_öÙhsCoÅ7žQö!h | h«ÜTÒ#lê$¤2P€Ÿg7”Çõ³;>Kõ7<Û*@º# –¢pšU3ÍÙðã�³ kcÞþ1Ï|®«´ªw-ÏÚÀî‰3AcMAÇŸy ¶™çª¥ÌÑÌ0B,ìwjIEËië5?j»jEÁ™ë­¿½Lå­ö`w<¹†Í=±†jÍÉ“¬ñkˆ5O¿CâZÏri‡¢X/'œÎ+ Ö|^¹H‰¦-¾[Â'äò wˆf{�#‘HÊB"ÿÍÁc@S»öÆ¢ÆoÈ€Z¤@"T-,vš‚ê¨rD&pLíá,£…alWcˆË4‡Ó¡+bÛÚÒì€A"&Á/:šR!"R`€E8ÑáœÈ…¤ŒˆE‡�ã¹HÆ2šñŒhL£×x„0àp„£þ"@Ç:‚ I¨c.·=*ÁGAµ�à�`�‘€ÈF"ÒŽD¤‰ÈEö±‘–4‚!É€6"2Hˆ@$É�°lr”š%� •Sf2 hd'‘pJ�¼R�¢<$(KUV2•ªLH-¹K"¸’ !pä$iéÈ9~’—‘4À0—iÌJ’ $¸&0m ‚�4Òøå%yK!L³¹@1…LLVSœC8%ä)„oá˜K8å&g¹Íg!ë€>=IÍw Wô(<͹PJ®²—5¨;…�P"´óå@F]éS>²ž5hFGÊt–SŸ¤ü§?)þ*É- Óž"•@#°Í‘2ô]é; pQu²T—Dè¥OµðÒÆS•8>“`Ï–n—ö¬è„Ð0@tÌdQqzÏQòT©ˆœÀS*�¡¶‘Xj'¥*ª¢s”üTè! ÇRv5’h9e@‹ ÔE²õ¨\�&ÿêV"¤³‘ëLhPÊIfbT ú<ç]@Ò¹ö§‰|k$‹Ö|Vr¢“iOUùÔ©Žr=½%–*WÊz§jëcCéK¶¶§lDÙéTÀÚ2›À}jOϪK,dE–q<e\okØÍ¡§=l@·êZƒÞ4³“m$++»JHÎu²ÐDl?énÆZ.·µ‘,ía…©JK^Ö´³½iR½kÛëªr·èudB`Š�²Á—‹$k1WŪ´¾ëj$ÀÇ©ÒõÁ æâ×Vi&�p�]ùj�$Àà æ„47|„@—{#‰çhbÑ*x•6e£p‚��;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/template2.html�������������������������������0000664�0001750�0001750�00000011167�12605311412�022650� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> <style type="text/css"> <!-- @import url("WikiPreferences.files/custom.css"); td.enable { border: 0px; color: black; background: #ccffff; } td.disable { border: 0px; color: black; background: #66cccc; } --> </style> </head> <body style="background-color: teal;"> <table cellpadding="2" cellspacing="10" border="0" style="width: 100%; text-align: left;"> <tbody> <tr> <td style="vertical-align: middle; text-align: left;"> <table cellpadding="2" cellspacing="2" border="0" style="width: 100%; text-align: left;"> <tbody> <tr> <td style="vertical-align: top;"><img src="WikiPreferences.files/yaws_pb.gif" title="" alt=""></td> <td style="vertical-align: bottom; color: rgb(255, 255, 255);"></td> </tr> </tbody> </table> </td> <td style="vertical-align: top; text-align: right; width: 100px;"> <br> </td> </tr> <tr> <td style="border-style: solid; border-color: white; border-width: 1px 3px 3px 1px; background-color: rgb(204, 255, 255); vertical-align: top;"> <script> if ("@@NODE@@" != "home") { document.write("<h1><a href='allRefsToMe.yaws?node=@@NODE@@'>@@NODE@@</a></h1>"); } else { document.write("<h1></h1>"); } </script> <!-- the generated page --> @@DATA@@ </td> <td style="vertical-align: top; text-align: right;"> <table style="width: 80px; height: 98px; background-color: rgb(102, 204, 204);" border="0" cellspacing="0" cellpadding="1"> <tbody> <tr style="font-family: helvetica,arial,sans-serif;"> <td onmouseover="this.className='enable'" onmouseout="this.className='disable'" onclick="document.location='@@HOME@@'" style="border-top: 1px solid white; border-left: 1px solid white; border-right: 3px solid white;"><small><small>&nbsp;Home</small></small></td> </tr> <tr style="font-family: helvetica,arial,sans-serif;"> <td onmouseover="this.className='enable'" onmouseout="this.className='disable'" onclick="document.location='@@EDITPAGE@@'" style="border-left: 1px solid white; border-right: 3px solid white;"><small><small>&nbsp;Edit Me</small></small></td> </tr> <tr style="font-family: helvetica,arial,sans-serif;"> <td onmouseover="this.className='enable'" onmouseout="this.className='disable'" onclick="document.location='@@EDITFILES@@'" style="border-left: 1px solid white; border-right: 3px solid white;"><small><small>&nbsp;Edit Files</small></small></td> </tr> <tr style="font-family: helvetica,arial,sans-serif;"> <td onmouseover="this.className='enable'" onmouseout="this.className='disable'" onclick="document.location='@@ALL@@'" style="border-left: 1px solid white; border-right: 3px solid white;"><small><small>&nbsp;All Pages</small></small></td> </tr> <tr style="font-family: helvetica,arial,sans-serif;"> <td onmouseover="this.className='enable'" onmouseout="this.className='disable'" onclick="document.location='@@LAST@@'" style="border-left: 1px solid white; border-right: 3px solid white;"><small><small>&nbsp;Last Edit</small></small></td> </tr> <tr style="font-family: helvetica,arial,sans-serif;"> <td onmouseover="this.className='enable'" onmouseout="this.className='disable'" onclick="document.location='@@HISTORY@@'" style="border-left: 1px solid white; border-right: 3px solid white;"><small><small>&nbsp;History</small></small></td> </tr> <tr style="font-family: helvetica,arial,sans-serif;"> <td onmouseover="this.className='enable'" onmouseout="this.className='disable'" onclick="document.location='@@ZOMBIES@@'" style="border-left: 1px solid white; border-right: 3px solid white;"><small><small>&nbsp;Zombies</small></small></td> </tr> <tr style="font-family: helvetica,arial,sans-serif;"> <td onmouseover="this.className='enable'" onmouseout="this.className='disable'" onclick="document.location='showPage.yaws?node=Hjälp'" style="border-left: 1px solid white; border-right: 3px solid white; border-bottom: 3px solid white;"><small><small>&nbsp;Help</small></small></td> </tr> </tbody> </table> </td> </tr> <tr> <td style="vertical-align: top;"> <hr> <p>Last Modified: @@MODIFIED@@ </p> </td> <td style="vertical-align: top;"><br> </td> </tr> </tbody> </table> <br> </body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/history.gif����������������������������������0000664�0001750�0001750�00000003176�12605311412�022256� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a0�+�÷ÿ�ÿÿÿ!!!111999BBBJJJRRRZZZccckkksss{{{„„„ŒŒŒ”””œœœ¥¥¥­­­µµµ½½½ÆÆÆÎÎÎÖÖÖÞÞÞçççïïï÷÷÷{ssÿ÷­Ö΄¥œJ÷ï„ïç{ÖÎkçÞsÖÎcÿÿ÷ÿÿïkkcZZRRRJÿÿçJJBÿÿÞsscÿÿÖZZJŒŒsRRBÿÿÎÿÿÆJJ9÷÷½ÿÿ½ZZBÿÿµRR9ÎÎŒÿÿ­ÿÿ¥ÿÿœŒŒRÿÿ”ssBÿÿŒ””JÆÆcÿÿ{ÞÞçkksRRZBBJZZkRRcµµçŒŒµÆÆÿ¥¥Ö���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ÀÀÀ!ù��ÿ�,����0�+�@ÿ�ÿ H°à¿  0X  8j80H±¢E(IÒAB 8�àÀ¡B‚ @�0A…‹0 2!5m.È€!Á„ l¨©¡ç?Ä´¨�ÃH§,/4`ÉòA <°PÁåÒ‚P ü{�…À¿°#Hðµ-Z²fÑ2�e@ÊF +à.Ú h[°Á9rÜ ÁxÆ‹+b$ P+a˜`µ Âf $,¨PÁÁÊ ¨3l�ð€Áe‚I9lŠšƒ$7(ð¡é…ß0<8ùÚ … 0L •‚À0¿[<¬õ¸bhðà.„²gÅ¢ÿ aóJ/?Ð1¤D =|ôèÁ#ñ )Š/EÀ䉋�®°Â '˜` ü�hà•~9àÀfX‘FÁ?‰FšJTa€ÀnbTAp8€Ap™aP(9ð�hÀÁ‚ @p[ÅEÐÀP0£µ `åOôÔ€  ŸI!eÐ�I�ôH• Ä�Xp„(P\@Õ™gjP@Xi•˜pê÷x˜å�]vý3�$°}ý³Vð†.5'vc=`ž¡p…')ZXç\œ—)À祗!„ A€@Ä$ˆ‚=| �¦M€ƒ|óñÿPß ´Ò0ƒ ,,àu˜N°;Ì ¬cˆÂDð"ˆqЄG´`�ÓžÉÁT�Á,I0œ D0£ 1§ÜrEVÀ!K„)¦h\¡/V¿•‡•i#‘Ä ¸ö$ôr`0Á\á[[Dp-¯™R¤ ðd“|™m‰ühRd€ãk< AŸ¬ €´ÀV$€ANF!¼jq¥AodHMzÖ€HbÀ>©@HLÒm#±vUWtH…˜€�HI•T_€¬.9œ P€æHœÙ$idZ¦( @ˆÄÒlA9X„íqp6«„nø¢ÿ,^A‘Ö1ªPºgŸžute–¢P8º¹X �è]‘Ž'žXdömLˆ£€�”CÊ'yE.é?|þÕ™û[P@�;�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/ftp.png��������������������������������������0000664�0001750�0001750�00000001034�12605311412�021354� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������óÿa���gAMA��ÙܲÚ��ÓIDATxœŒ“=KA†ÇS€!×ZØÄk±óE ‚©Å ‚……Ú¦X$…`!¢?P‚FBÌå$¶BÄSÐS´ ±s»ãΚ Ùã@^fgvßgg‹DÒðð&’Âáå°Ûû`&’ƾ¾EŒÇß0™DœæP}M=_0D¦¶±TBœŽJÐêÚƒÚÝeNµ&'¶$À~äÒH :H Dâ«!D{ `b|SÌKŽEƒ£eùƒ¨GëPhIŒm i"œ¿`˜Ë1Ìž;¾ X,½½ *`t$……‚kv¤ùô´†™L ¿ñèèWWÊ ÎIXwp^´1Æ€s”b@”ÀIèÖâ–z|¼Û¢Wƒæhãâ4#³0!Á~”IÍÈ”Zc@7º·SvÜÚ3…w&Èfoáî¶µ1‰|û÷�8s@×õN¡€!Ð*•û““uH§ã`îàÉn¯›Aš ª�¸CiF¨_×o:´b1‘j©VŸ ìY l›S† OÐ…(kîF3È4wà`?ÆÅ”¯ý&øz²4ð„T0öàåµê9cYVåÏïÚÓ3îꊢ®J”P§»ÿ��ÿÿ�¤8,% ʯ����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/mailto.png�����������������������������������0000664�0001750�0001750�00000000421�12605311412�022047� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR������ ���²Õ���gAMA��ÙܲÚ���tRNS�ÿ�ÿ�ÿ7X}���tEXtSoftware�GraphicConverter5]Hî���‘IDATxœ¤’Q À ‘€4` XÁZЀ,`a»¤ !¬,Ùö>šGÛ£ ›9¾Êü"Í­¤s®”ò0*= Ù{§sV1òTéQH9„bŒ F†üÕ½#QJÉ{Ïõx"~^dKÊÎL ¶Öˆ ”=ŸHÁj­x¢µvøo_HZï°þUvØ +ä‡?á��ÿÿ�0kÝñŠè(����IEND®B`‚�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/editme.gif�����������������������������������0000664�0001750�0001750�00000003152�12605311412�022016� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a0�+�÷ÿ�ÿÿÿ!!!111BBBJJJRRRZZZccckkksss{{{„„„ŒŒŒ”””œœœ¥¥¥­­­µµµ½½½ÆÆÆÖÖÖÞÞÞçççïïï÷÷÷kccZRRRJJsccRBBB11ZBB{RRZ99kBB„BB½ZZÖccçkkïkkŒ99kcRœ{!¥„!çµ!JB)sc1ÿÖJέ1½œ!Ö­!Ö½RÿÞRÿÞJïÎBskBÿçcÿçRÿçJÿïcÿ÷”ïïçÿÿ÷ÖÖÎççÞÿÿ便”991ÞççkssZcc½ÆÎççïïï÷÷÷ÿÎÎÖÞÞç„„Œss{çç÷kks{{„ÞÞïcckRRZZZcBBJ­­Ækk{ÞÞÿccs))1ÖÖÿÆÆïJJZssŒkk„BBRcc{ÎÎÿµµç­­Þss”ÆÆÿ¥¥Öµµï­­çssœŒ„­ÖÎïÎÆç”Œ­kc„ƽ޵¥Þ¥”ÎïçÿÞÖïÖÎç­¥½œ”­{sŒkc{½­Þµ¥ÖZRkRJcƵ筜Υ”ÆçÞ÷¥œµ„{”µœÞν罭ֵ¥Î­œÆœŒµÆµÞ½¥Þ„sœµœÖZRcïç÷÷ïÿÖÎÞµ­½­¥µ”ŒœŒ„”sk{kcsÞÎïÖÆç½­ÎRJZ½¥Ö{kŒµœÎsc„œ„µïÞÿçÖ÷Î½ÞÆ­ÞkZ{cRsçÞï÷çÿïÞ÷cRk÷ï÷ÿ÷ÿÎÆÎçÞçµ­µœ”œ{s{sks„{„kckZRZcZc���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ÀÀÀ!ù��ÿ�,����0�+�@ÿ�ÿ H° Áƒ),ñA‡<r¤ÈŸDû4j4Ç”©9·jôÐa£Å†+• ªø�S)<w©*Š$IK\¹b€OŸ ®T¹ ÂÏ£HJ@³ÅË2†ÔE•jA«V!@@°ê„U¥¬jõŸ]è»ö´c× ÀV º@Ja‚„4`  .+žþðÙgQ¢@bXäHBKDLbZÙØÑ"8xBãQUè %Iv$eÄV‚Ì) P‚3' =“jÀp!H!¸Â68aAÒã?¥Œ!2¼kU±®µê�îØ�( -Õ³m›«ÿì ‰‡(R Î!HŽü8úô c¢>}5‚ã‡ÃŒ1ÜàBP Þ?üqŠ}œu'w䀬‡“ÌâÀ-¦àÁ‰h1ͤmµí€È¡,µDAŠK,¡nÈ@ „À<½’£OD´±Å‘^˜ÅW>�ÁHi EkX!T²ù´[<@X$ À <Ue tÖ[ki÷Z–Z œ¥–@à%À†¥Ýt€þStqU§‹¡š¥@Œ6ª’”€‚ r:*P_]:°À-àÉ� < ) !ˆg� ©!J¸ÁÈ ‚\ÿÔ"ˆì×È-˜ƒ¦¯‰W#¡I(]tgˆ(Ò ;Hà gè€(}{,G!ò† á0bÇÑŠ7ú5èÞQ‰�]ÔòÀvDÁ„% 0Š@'ˆx%#Â!«D±N;ÅR©x èñ†h›È4ãM9¹‚£OU¸x`S°RâL6!ÌSnHAð�– °Bm5ZÌ”ôÊ!ªè„ÉQ@Fa h,^M@ùU¬áE[œq£AýÓ\¤±… ‹RûÄlXQ.‡(�epù�|ZŠ@ab’iæB[J•v„Æ¥¨ ÖýGy¨¡áIõݘáe€tÿt¡Kœc @ð–@jNWŸïUâƒ:xâ ÑÝnþÓÝáV@¾N@•ëmUž—¥Œ�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/url.png��������������������������������������0000664�0001750�0001750�00000000552�12605311412�021371� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������èѸ���gAMA��ÙܲÚ���tRNS�ÿ�ÿ�ÿ7X}���tEXtSoftware�GraphicConverter5]Hî���êIDATxœœ‘Ý„0 „] -¸j™h܈G$Zp +ZÉÍ8Üívö,ˆ¢èódƱöMÙÿéó<#�ø4MÜìûþ‘•gÚ<ÏÜpˆ7t¡ÑÒ2=Ã" ‘¢ì×@f‚ÂÕ`˲°—åÝ!¡?Z²Ù$%ôÙx­(wš—ÇA‚’R‚<\µ‡ax ëª¸ô®¸Yào/´â+SG[9±žµ s½ÓÛv«ì©XjQ@tÀH?¥ìf¼†Õg…öwó:(—œ@ Á5r·q?¾üº®%] OÉú��ÿÿ�ã’Ã’d ׋����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/zombies.gif����������������������������������0000664�0001750�0001750�00000002727�12605311412�022226� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a0�+�÷ÿ�ÿÿÿ!!!)))111999BBBJJJRRRZZZccckkksss{{{„„„ŒŒŒ”””œœœ¥¥¥­­­µµµÆÆÆÖÖÖçççïïï÷÷÷JRR!))!!Bc1J9cBsÖç÷œ­½9BJ9JZ!))BZ!1JRZ!)1c{”!1B1{Æ!Z”9csÎ19B9k¥JŒÖ9„Ö)c¥c„­RsœJk”c”Î9Z„Z”Þ1R{J„Î)R„µÎï”­Î9RskœÞRŒÞ”µç9JcZ{­9ZŒ)BÎÞ÷­ÆïŒ¥Î{¥ç)9RÞç÷{„”Zcs9BRŒ­çBZ„!1çïÿ„ŒœÆÖ÷½Îïk{œ”­Þ!)9µ½ÎRZk)1Bœ­Öµ½Ö¥­Æ19R÷÷ÿµµ½ÞÞスΥ¥µZZc119!!)cc{RRk11B!ÎÆïÎÆÞÖÎç{sŒïç÷çÞï÷ï÷œ”œRJR������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ÀÀÀ!ù��ÿ�,����0�+�@ÿ�ÿ H° Á*\ÈðŸ \qAÄɉ_¤ñbâ_ƒ,4é1AÖ$8ÁB�.� €¤MƒZ p’à:gîÜ1“à¦=H÷Üü‡”`Ó¥“"0aÀž˜ÐÊu£ ˜*`ë?V d½iá�Pñ¡‹€þI€º4Â'Ø^c¢@x�0Éצt:H  oc’.P°—a¡&ØST¬é=[QwUÚ´õžMp@õ2Áš+Û©`D  h$©‚Œ‘¥w<Ð ì 5ªèp¦I-kH¤Y°@€r†¸ÿ1! 3PXœ¡è‚"¿´PàÀ] p–ÏPBø=f™@ àF ¨\‘ä€�TA�p@ lÅ߆ )°ÇÿTuUV$@ÀœXGEfÀV"Á?zµVA£%çZW©¥ÆÚ¦5§†{ Àá‘F)!(¸P¸!ùO^ |7Xñ 9‘À’G6ƒ VØàB;tAÅ-¶×Íõd›d%/�LñF`±e $el¤ðFL!DK¬À@~€$edPÑÄ ZŒÁÀ�D Ó")AMH¡Eõ°@ ¬¯D@3N á‘$°�Š‘šÀ”IY€ÂŽ´@”MP@À ¡!mˆWB $'uÈAǺ}W@Bï´@vl Á�ÈÎi€Xð€€)² °±—œÅæ«oA pb�K=%U€ÔI¦R 0¼°Â95uâh9ÉA‘ ¼GO;.Üãi@"õâV0bBH}eÀGö±Çb°ÄÿÀ�¹¯M�;R�;�����������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/interwiki.png��������������������������������0000664�0001750�0001750�00000000465�12605311412�022577� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR������ ���oí¼���gAMA��ÙܲÚ���tEXtSoftware�GraphicConverter5]Hî���ÇIDATxœbøÿÿ 50”Á@!¦¡A@ÀÄÁ@l…$…hêÒx*†A@ ÄËø>�â@$M‹øwBù¦@|ˆŸ`3$yˆÿCñ¨¸%߆ŠýC2| Vƒ ’Ó á}P"‹mâ ¾ ÄÉøÂhÈf$ ƒö�ñ/$±o@ÜD(°M€ø7’¦f¨øK$1kLF?È6¨ ®±T,ˆ?C#˜ètUhΉÅñL|éˆb ���ÿÿ�Àkï>é}ñ����IEND®B`‚�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/edit.gif�������������������������������������0000664�0001750�0001750�00000002417�12605311412�021477� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a,��Æ��-#â±jîæÜíæÛ('&ûñâèâÙöíàöÁs0&·VãÞ×ïçÜ+") Ò¥cýòãüòâÞ®hî»qêãÚéãÙ$#ùðâøîá÷îà1'0%é·oäßׯ›]òêÞò¾q,#*!þóãä³m³ŒTï¼qëäÚ%΢aùïáûÅvÚ«fê¸oôëßöÁtóëÞòéÝ.$,"˜[ñ½rüòãúðáüÆv¯‰Rì¹p»’Wê·nçáØ"!ÊŸ_õìß/%Ö¨dçµnó¾sðèÝïèÜýóãüñâþÇw¾•YøïáùÃuöíß«†P1&0&æ´lãÞÖô¿sñéÝ-$,"+"å´nìåÛî»p&úðâøîàúÄu2'çáÙåß×÷Âu������������������������������������������������������������������������,����,���þ€V e„ V@@d*‹*]IJD a:`:Q134X¢]*§d@«‹]*JJI D-:```-œŸIXÈ¢¥fŒ§ª§¤]·X"44Q»½™:-a žØ"3X‘AB¦³¨]ËÈ4"ø aÁþš-Ä)7c†,J2`È N�Rܸá¤bFX B¡Ê#ˆY¥d�#F"h bÈ _VdC胖C4AIáEÊ�EŠ£À‹—UøLÉ¢éÆ_¾üä$Ä Œ(UR@¡§‘*B›ˆ‰”ë YYDPI€@(þÛ8¬5ò"€Ò”[”¬âeÄP¡#ŽEZrë ŸJ@  /L‹®/’š5bè¾"‡‰9ðÑÂ\ØP\I‡Ž?€JîÙÑ#HžQ{Q�[L¢#.{1IÁÆL·=R¤—"5Š(ŸB›6HåF‹P±½ƒ(í‘ ½�ðmbI÷&;ªƒA¥Èæ¡¶#7JeŠmcĽM´Èö%rHp~cP!’X·5›5Ô€_"í0Æ.¸@à·!gCæ ƒ g@qÆðáŠ1ÅäñÑñ=ø u"j¸¡‡ºØÁƒÕ=ØÄ'z!Æ‹ðu�Œà‰þõà90áWpÈáStÐá‘=Æ÷ã#l!G˜¤‹”y�H\C 8àP„W tŽa%бCSÐYå‡ù!Ÿ ›8T hʱ‰ |nX¥ PœøáŸ~øá'Na()°Y 0|\¨iÊPéW,°À.P9Å l¥‡’¾Ú‚€Aê¨Á¨rozਫ­Î*ëP.»@³g Á¦,ðÄ®`|�CÛC¡†ª(¸iÊ å¹æÊ™&”à¦@ìµ-d{„¶¿†»è·m¦‹šj¶é¯ºã"W¼1o·ôö ðÂ0€Û&¢æŽ«h¸)w,œ`×^ËÅ sqð=ZêÂ)´+'W¤@jÈãVÜm��ðÄÌ-��s 0g‘`‚È휱 ¼tÏ;+·3�$ÐÂÌ$ÄœÌ6ûŒœÎR1´=ßÌóÅZt½Á<ÐuÒI;sÌeŸ µÏ:çL5Ò$hv �;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/forward.gif����������������������������������0000664�0001750�0001750�00000000573�12605311412�022217� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a � �Õÿ�ÿÿÿþþþýýýüüüûûûúúúùùùøøø÷÷÷öööõõõôôôóóóòòòðððçççæææâââÝÝÝ···šššdddaaaIII???<<<;;;999'''&&& ���ÀÀÀ������������������������������������������������������!ù��-�,���� � �@˜À–pH,È!`ÉdZ2@”™,š®X,èºÅfªà°xLV6™ˆI6óXŽÏKD%ÛY¶Ëø¼~¿—"¦kmTbYY]‡cS~qr^�opW„R•|Ÿ ¡¢£¤¥IpR™&Žnb¨rtvžaMŽ’W”c‡ˆ¿&_†Á‰kŒ¯°j^„oSƒM–MOQ­¦ÛÜÝbA�;�������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/template_info.html���������������������������0000664�0001750�0001750�00000001014�12605311412�023567� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <head> <title> @@TITLE@@ </title> <style type="text/css"> <!-- @import url("WikiPreferences.files/custom.css"); --> </style> </head> <body> <table width='100%' border=0> <tr> <td> <table width='100%' border=0> <tr> <!-- the menu --> <td id="@@MENUID@@" valign='top' width='90%'> </td> </tr> <tr> <td> <p>&nbsp;<br /></p> <!-- the generated page --> <h1>@@HEADER@@</h1> @@DATA@@ </td> </tr> </table> </td> <!-- the right hand image --> <td width=10 align='right' valign='top'></td> </tr> </table> </body> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/back.gif�������������������������������������0000664�0001750�0001750�00000000572�12605311412�021452� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a � �Õÿ�ÿÿÿþþþýýýüüüûûûúúúùùùøøø÷÷÷öööõõõôôôóóóòòòðððçççæææâââÝÝÝ···šššdddaaaIII???<<<;;;999'''&&& ���ÀÀÀ������������������������������������������������������!ù��-�,���� � �@—À–pH,È!` @43¦t™,fLX»ÍzMÕ°xL.+kvâœRÇèeÇ[iOÍø¼~¿—¦½K„�d_Z‰Xd�j&m…Lvs&vR| ¡¢£¤¥¦US›n†p‚�›Xu­Y’–MŸc^]‹d·‰À_h¾l­ÇKˆXƒ…Í»P­o§ÚÛÜaA�;��������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/http.png�������������������������������������0000664�0001750�0001750�00000001064�12605311412�021545� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��� ��� ���Vu\ç���gAMA��ÙܲÚ���%tEXtComment�$0152: 1*Short:1 $935C: ???? ŒeÌ×���tEXtSoftware�GraphicConverter5]Hî��•IDATxœbàà‘×åâ×qa ðúkÛví•׉jàÒ°c``bÅ«‘‰MFHʪÎ2pñ+ßÌ /û*èùq È02±ó`ÓÃÄ2\üJ¹N1³TϹý·mñ•_ñuÛ^YúUÏàä“VÂj‹Èi¹÷”O¿òmÞÁÿ+>ùo;ç&¯Œ¿Èë…äÏ=?uÛƒ_Svÿú“3õþ7QE« ÄxDÔŒngFò+·¹OÅôâ9Oþwnþñ¯{û ýþ_XÙÒKšŽåËÍB&ìbdbáG¶€ƒ_ Ã8xâíø¾?+V~ÿÛ°þÛϾݟþ•/~ô×>aÃFqt?ˆ±° DÈ™%l h¸ð#uæ÷©³þýO˜üã¿Yè† ,’ؼÂÁÈÌéd±ðfâ¤÷¿ƒ;¿þñ®{ÿÇÀoåeFf Õ̬|BR:©mý k¹ó?´åÑŸŠ;ÿuÝÞjÀ´[ÆPL5l°’÷!U·ÝÂjîûÜöð‰[MºZ¤���ÿÿ�æŽê3°m����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/home.gif�������������������������������������0000664�0001750�0001750�00000002722�12605311412�021501� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a0�+�÷ÿ�ÿÿÿÿ��ý��÷��ö��î��í��æ��ä��ß��Ü��Ù��Ø��Ö��Ô��Ñ��Ð��Ï��Ì��Ë��Ê��È��Ç��Å��Ã��Á��¿��¾��»��¹��¸��·��¶��µ��´��³��²��±��°��®��­��¬��«��ª��©��¨��§��¦��¥��¤��£��¢��¡��Ÿ��ž��–��“��’��‘����Ž��‹��Š��ˆ��‡��…��ƒ��‚������~��}��{||{��z��y��x��wwww��v��uuuu��t||tttt��suussss��r{{rvvrrrr��qyyquuqttqssqqqpttpppoqqo��noonnnmmmm��lmmllll��kkkjjjiiii��hhhh��gggg��fffe��cccbffb��````��_ee^��]bb]^^]��\bb\\\[bb[[[Z__ZZZWWWVVVUaaTccT��RRRR��P��OOONXXN��M��KKKI��HHHH��FHHF��ELLEEEDTTDGGB��ADDA��=��<��:;;:��9999��8��7887777��6��5��4442��1��0��///.00.��,,,,��+//*,,***)**)��(33(��%,,%%%%��$��#$$#�� ������....����$$���� ��  ������� ���ÀÀÀ������������������������������������������������������������������������������������������������������������!ù��Û�,����0�+�@ÿ�· Hp›¡WÎx*(É6$~ädJøÌ!ËBÛx)ÀŽBØ8¦Œœ“(Ë”ÉôÊQh¡2ÊܭȽvˆ `!– N  ƒ†ª†“KÉf*½ˆ$ÓFhŸ6:³¸´êƇÐVݪô*’g ‘8ƒ†Ì!´W4Ñž}8¶,W†HP}`¶1@P^%Qê•£Òi™· ¡í ydÈÐ45ñ#å,¢@Nh€˜ 327Ÿ é"*5v891ç'¨U^Í:ãÓj)_]K{áF9WY?ÓÀ»×S^~ ùiR¦‰qâ‹É¶ˆäé ; 4€–-ï^”.ÇV~ÊŒgȧ†QAÿÛc’¯ŸS¯21Þójc¦íƒã˜.ŒÌ‰æ+r¢¯ÖÈlöf!5àBQ.�±ÑP@Ä2ÇË!ÊkÐÜ€ 74ðÉ}¨IEÕr †(âv”52ÐðâÐ)ŽðM.:$4S±æUV4É&›m<æ¸ÍI#¹3Š,ãÛ6¯¸H!YϼrÊ)Ï<#¢!d|p…Ä™T^JeÍ{ BC4'X04|]Çe{­5· ìðAH@cÉ–{•áÈ)MDI"4Ë àB�81g�“Á¢’^]¾âh&H”͇U9‚ÊNO™ù4y™’É#R B 4u²Öœ|ƒõ’&É@ÓK•'œ¨àªÙHÆç™¬5 4EÜ� „«A£AfÝ@.øÔ2dÔ „"d[/@ lHœK @½IÆ'±áLk¸Ag,Oe;À8;ë ãnäH>ÅÇ­#ž½BÊ„D{1lðÁ'¼ÕZ)\Ðm^.ä4Ç´‘—ÐD¼ ,ÌLlí[EŠãl;ÒÔãFè5 ÃÛœBñÈ'/äâÄç:ÜZ@�;ûpk�;����������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/https.png������������������������������������0000664�0001750�0001750�00000001457�12605311412�021736� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������óÿa���gAMA��ÙܲÚ��æIDATxœœ’kHTQÇçÞ½Þ]ë+u53)]ÍJÖ$E?dë.ŠF"EáMS”Ä@0”ò‰‘™`’’}ƒ ìa¤_* ,-4",Íغ!»®w÷1»JQ”Dÿ{àÌÌofÎ��66¥ëåîm¯i…ÒþÃÔþ¡úÚ¬Š)>ëôê2n¬†D©#÷Šxí§(Eþž´›–SÍŸ± ~ ŃRÒѾ¥ úbâ§·PrD:¢mê…¹µÏq`ÄŠ­·ßayóc4– 9×f¼¢nÆÿÑTDZ¢ºŒ¶™¢Öql¸eÆ‘i‡^,cMÏ$Ö ÌatrUË߯c KGêë?Í74÷¹:ï.`÷#;81¿} õ•O%uHbÙf±_ŒÖé‡ ãlnnÞû‚’jgIYžolÁ®‡læ0§ázÆ\‘ßK.ö; ,==c™¦éÊq™£™ÅMXÕØƒE%åxæÒ(¶Ü°²{‰'qF"?°ÏpaœŒüºM+4AAÁÊàˆ¤ðãUMé‘ñÙ@¦ ¸µUðóu‚&ÌÁä·<{®«¸¬Õ_Ü{8û$ÉõwòòŽõj4ߎ‹Õ5É3"M:,-Á6j¬6¢µ‘¦¢ Ï-KÎ<‡.wÀ—zWGG+Í0¬—ÃápÏäp8!%):»¯ÃúŠV,jˆØ 1±à¡’`ôþ'9L)h9Él¶Ë*ÁdúꬭYa~~,V xp@ÚÞLKàrI�(¥ÜqÌV&›Ä‹hç<)—(‚“G\$™A$ç�EQ€(ÓiQÜp‚�îq( Ôì xùùÀì¢/-ø8÷޳¬Êƒa<@– “ÅópG¼«Vo°ÛÉŸðç‰ða¹µŸLLŒ¿íïïߨì"ËJ?›ÍBÍ|1Ã7Ó`=U Hį‹ t¯Àw���ÿÿ�™É+ð6 ����IEND®B`‚�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/template.html��������������������������������0000664�0001750�0001750�00000003100�12605311412�022552� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <head> <title> @@NODE@@ </title> <style type="text/css"> <!-- @import url("WikiPreferences.files/custom.css"); --> </style> </head> <body> <table width='100%' border=0> <tr> <td> <table width='100%' border=0> <tr> <!-- the menu --> <td id="@@MENUID@@" valign='top' width='90%'> <table width="100%"><tr><td id="menu"> <a href="@@HOME@@"><img border=0 src='WikiPreferences.files/home.gif' alt='Home' title='Go to initial page'></a>&nbsp;&nbsp; <a href="@@HISTORY@@"><img border=0 src='WikiPreferences.files/history.gif' alt='History' title='History of page evolution'></a>&nbsp;&nbsp; <a href="@@ALL@@"><img border=0 src='WikiPreferences.files/allpages.gif' alt='All Pages' title='Lists all pages on this site'></a>&nbsp;&nbsp; <a href="@@LAST@@"><img border=0 src='WikiPreferences.files/lastedited.gif' alt='Last Edited' title='Site editing history'></a>&nbsp;&nbsp; <a href="@@ZOMBIES@@"><img border=0 src='WikiPreferences.files/zombies.gif' alt='Zombies' title='Unreachable pages'></a>&nbsp;&nbsp; <a href="@@EDITPAGE@@"><img border=0 src='WikiPreferences.files/editme.gif' alt='Edit Me' title='Edit this page'></a>&nbsp;&nbsp; <a href="@@EDITFILES@@"><img border=0 src='WikiPreferences.files/editfiles.gif' alt='Edit Files' title='Edit attached files'></a>&nbsp;&nbsp; </td></tr></table> </td> </tr> <tr> <td> <p>&nbsp;<br /></p> <!-- the generated page --> <h1><a href='@@ALLREFS@@'>@@NODE@@</a></h1> @@DATA@@ <hr /><p>Last Modified: @@MODIFIED@@</p> </td> </tr> </table> </td> <!-- the right hand image --> <td width=10 align='right' valign='top'></td> </tr> </table> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/index.gif������������������������������������0000664�0001750�0001750�00000000215�12605311412�021653� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a � �‘ÿ�ÿÿÿ ���ÀÀÀ!ù���,���� � �@^„©Ë턜hÒc¥Ê¢fo)ÁH"dyœ#Ķî DzXiãÓ=Ãx1üzÄ"æs %ƒÆ¦ÓXÛé$<C”*R™´)îó ~ …H²¨Y¦Ḭ́ûGÊó³ºsGãáï�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/WikiPreferences.files/template_info2.html��������������������������0000664�0001750�0001750�00000002266�12605311412�023663� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>@@TITLE@@</title> <style type="text/css"> <!-- @import url("WikiPreferences.files/custom.css"); --> </style> </head> <body style="background-color: rgb(102, 204, 204);"> <table cellpadding="2" cellspacing="10" border="0" style="width: 100%; text-align: left;"> <tbody> <tr> <td style="vertical-align: middle; text-align: left;"> <table cellpadding="2" cellspacing="2" border="0" style="text-align: left; width: 100%;"> <tbody> <tr> <td style="vertical-align: top;"> <img src="WikiPreferences.files/yaws_pb.gif" title="" alt=""></td> <td style="vertical-align: top;"></td> </tr> </tbody> </table> </td> <td style="vertical-align: top; text-align: right;"> <br> </td> </tr> <tr> <td style="vertical-align: top; background-color: rgb(204, 255, 255);"> <h4>@@HEADER@@</h4> <!-- the generated page --> @@DATA@@ </td> <!-- the right hand image --> <td style="text-align: right; vertical-align: top;"><br> </td> </tr> </tbody> </table> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/FormattingWikiPages.wob��������������������������������������������0000664�0001750�0001750�00000024405�12605311412�020325� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ƒhd�wik002k�lockedjhhb��Óa ahaaak�unknownk˜*Character formatting rules* - * '''\*bold\*''' produces *bold* words. - * '''\'\'italic\'\'''' produces ''italic''. - * '''\'\'\'code\'\'\'''' produces '''code'''. - * '''\_underlined\_''' produces _underlined_ words. Paragraphs are separated by a single blank line. Headers are written as '''\=\=header 3\=\=''' ==header 3== '''\=\=\=header 2\=\=\=''' ===header 2=== '''\=\=\=\=header 1\=\=\=\=''' ====header 1==== ____ *Column one control characters* Some character sequences have special meaning if they are written starting in column one: { { Preformatted text is written within curley brackets. } } { [ Notes are enclosed in square brackets. ] } [ This is a note. Note that the *only* character on the start and stop lines should be the characters [ or ]. No special formatting occurs within notes. ] { [expires:"4 Jan 2010 00:00:00" Expire dated regions are enclosed with square brackets. Normal formating occurs within the region. ] } [expires:"4 Jan 2010 00:00:00" This is an *expires region*. Note that the *only* character on the start and stop lines should be the characters [ or ]. Normal formating occurs within an expires region. ] '''\_\_\_\_''' produces a horizontal line. ____ *Password rules* Pages can be assigned passwords when the page is first created. If a page is assigned a password then it cannot be edited without supplying the password. Follow one of the links to see examples of: - * ~ALockedPage - * ~AnUnlockedPage Bulleted items are written: { - * Line 1 - * Line 2 -- * Line 1 } - * Line 1 - * Line 3 -- * Line 3 Wiki text has - [formatted item]These are inlined - [notes] These are set in boxes Column one has - (N times) The grammar is (-)+(white)+(\* | [Text]) (white)+ Stuff The tab level is determined by the number of -'s then we skip white space and look at the next character. This is either \* or [Text] then we skip blanks and get to the body To include some preformatted stuff we do { { This is preformatted } } With the braces in column one. [ This is a note. To create a note enclose you text you want in square brackets. ] We can defined writable region ''within'' a locked page. The entire page can only be edited by somebody who knows the page password. But individual regions (like this) within the page *are* editable. To edit the region just click on the ''Edit'' link at the bottom of the region. To define a region we add a block like this: { < ... > } The brackets must be in column one. The region will be colored ''pink'' to indicate that it is writable. < This is a writable region > A write append region is written: { << ... >> } << This is a write append region within an otherwise locked page >> To make preformatted text we write { This preformatted ... } With the *>* and *<* characters written in column one. Note we have to quote these in html. What about etc. do these get correctly rendered. Links are written \~TheLinkName With the grammar \~[A-Za-z]+ Links are formatted in Blue if they exist, in Red with a ?? if they are missing. A link to ~TestPage or ~anUndefinedPage are written in the same ''\~theLineName'' is the way to do it. Html lines are written in line thus http://www.bluetail.com are just written as is http://www.erlang.org/~joe and the special \\ character is used for quoting things. Externsions .src, .gif etc are auto recognised. This http://www.erlang.org/images/erlang.gif is an image Embedded HTML is enclosed in curly brackets. { This sentence contains a {{ <a href="http://yaws.hyber.org"> link</a> }} link to yaws. } This sentence contains a {{ <a href="http://yaws.hyber.org"> link</a> }} link to yaws. Pages are written in the file system with conventional wikie names. *Special Targets* To create a mailing list target of all email addresses on a page use '''mailtoall\:TargetName'''. It is also possible to create a slide show of all images attached to a file. This is done using '''slideshow\:NameOfLink'''. It will produce a link to a slide show of all gif, jpeg, and jpg files on a page. *Plugin* I (mailto:mickael.remond@erlang-fr.org) started to build a plugin architecture. You can now use two examples: dummy or backlinks. Here is the output of the dummy plugin: <?plugin dummy ?> ''Improvements to this text should be mailed to'' mailto:jb@bevemyr.com. If you want to edit this page use the password ''locked''. jl���hm���ƒl���haaÁhaÉaÑjhhb��Óa ahaaak�unknownhm���=ƒl���haa'k�''''____''' produces a horizontal line. ha4aÊjhhb��Óaahaa5a-k�unknownhm���¯ƒl���haa¬k�CPages are written in the file system with conventioanl wikie names k� k�K''Improvements to this text should be mailed to'' mailto:joe@bluetail.com. k� ha¹a¿jhhb��Óaahaa4ak�unknownhm���!ƒl���haak� k� ha a haa·jhhb��Óaahaaa*k�unknownhm���âƒl���haa¢k�g This sentence contains a {{ &lt;a href="http://yaws.hyber.org"&gt; link &lt;/a&gt; }} link to yaws. haak�XThis sentence contains a {{ <a href="http://yaws.hyber.org"> link </a> }} link to yaws. k� ha¨a²jhhb��Òa ahaa3a"k�unknownhm���‰ƒl���haaha¡a¢k�[ This sentence contains a {{ <a href="http://yaws.hyber.org"> link </a> }} link to yaws. haaha¦a§haa ha¨a²jhhb��Òa ahaa3ak�unknownhm���Ôƒl���haak�Z This sentence contains a {{ <a href="http://yaws.hyber.org> link </a> }} link to yaws. ha a k�WThis sentence contains a {{ <a href="http://yaws.hyber.org> link </a> }} link to yaws. k� haa±jhhb��Òa ahaa0ak�unknownhm���ƒl���haahaa±jhhb��Òa ahaa%ak�unknownhm���;ƒl���haakk�test k� asdfasdf k� k� halazha|a~ha€aªjhhb��Ñaahaa0a&l���aIadaeanata=l���a{l���k�oka,k�"dotter.bevemyr.net"ja}jk� jhm���'ƒl���haakk� k� hapa}haa€ha‚a¬jhhb��Ñaahaa0al���aIadaeanata=l���a{l���k�oka,k�"dotter.bevemyr.net"ja}jk� jhm���šƒl���k� haa)k�|is assigned a paggword then it cannot be edited without supplying the password. Follow one of the links to see examples of: k� ha,a¨jhhb��Ða ahaa#a3k�joehm��ƒl��� k�‘This is a ''locked'' page - note it has a red border. To edit this page you will need to know the password. ''It's the word *locked* if you want k�to help improve this text''. k� k�’''Even though the page as a whole *is* locked you can still change text in the green regions (such as the one below) without knowing the password k�Hto the entire page!'' - try clicking on the ''edit'' link below to test k�this. k� hakakhaoaqk� haa*k�Pis assigned a paggword then it cannot be edited without supplying the password. ha/a©jhhb��Ða ahaa!ak�joehm���¯ƒl���k�‘This is a ''locked'' page - note it has a red border. To edit this page you will need to know the password. ''it's the word *locked* if you want haak� k� haa²jhhb��Ða ahaaa k�joehm���‚ƒl���k�lThis is a ''locked'' page - note it has a red border. To edit this page you will need to know the password. haahaaªjhhb��Ða ahaaak�joehm���vƒl���k�KThis is a ''locked'' page - note it has a red border on the left hand side k�border of the page. k� haa¨jhhb��Ða ahaaak�joehm��� ƒl���haa¨jhhb��Ða ahaaa%k�joehm���)ƒl���haažk� k� k� k� k� k� k� jhhb��Ða ahaaa$k�joehm��gƒl���haak�0Paragraphs are separted by a single blank line. ha a k�*Block rules* k� haak�(The start of a pre-formatted region is k�Zindicated by a line with a single '''{''' and terminated by a line with a single '''}'''. ha+a+haak�CBlocks enclosed by single lines containing '''[''' and ''']''' are k�formated as ''notes''. ha a ha a ha'a¥jhhb��Ða ahaa a)k�joehm���=ƒl��� haa k� k� ha#a’k� k� k� k� k� k� k� k� jhhb��Ða ahaa8a%k�joehm��ƒl��� k�*Wiki formatting rules* k� k�This k� ha a k�9This is \*bold\* and \'\'italic\'\' and '\'\'code\'\'\'. haak�9produces "This is *bold* and ''italic'' and '''code'''." k� k�IAll character rendering modes are reset at the start of a new paragraph. k� ha#ašjhhb��Ða ahaa7a�k�joehm���,ƒl���haak� haaIk� says Jocke haKa„jhhb��Ða aha a�a+k�joehm���7ƒl���haaEhaGaHhaKaLhaNaUhaWaWhaYaYha[a\ha^a„jhhb��Ða ahaaak�joehm���ëƒl���haa,k�!With the braces in column one. k� ha/a=k� &lt;open tag="identifier"> k� &lt;txt> ha?a?k� &lt;txt> k� &lt;/open> haahaDaIhaRa]k�:With the *>* and *&lt;* characters written in column one. ha_a|jhhb��Ða ahaaak�joehm��ƒl���haak� produces k� k�.This is *bold* and ''italic'' and '''code'''. k� k�JAll c haracter rendering modes are reset at the start of a new paragraph. k� haahaahaa'k�This is preformatted k�Even comment get preformatted k�etc. All we have to do haak�! k� ha/aujhhb��Ða ahaaa%k�joehm��§ƒl���haak� Character encodings are simple. k�2Enclosing a character in \*bold\* renders *bold*, k�&\'\'italic\'\' renders ''italic'' and k�%\'\'\'code\'\'\' renders '''code'''. k� k�K''All character rendering modes are reset at the start of a new paragraph. k� k�BSo that this paragraph is in plain font, and not in ''italic'' as k�you might have expected. k� k�Now a load of bulleted things: k� haak� haaujhhb��Ða ahaa3ak�joehm���ƒl���k� haaojhhb��Ða aha aa$k�joehm��·ƒl���&k�<wik> k�<txt> k�@<!-- can be placed anywhere (except inside a tag or string) --> haa@k�</txt> k� k�<open tag="id1"> k�<txt> haCaCk�</txt> k�</open> k� k�<write_append tag="id2"> k�<txt> haGaGk�</txt> k�</write_append> k� k�<keep_until date="2000-11-12"> k�<txt> k�'http://www.bluetail.com/images/new.gif k�</txt> k�</keep_until> k� k�<txt> k� haJagk�</txt> k�</wik> k� k� k� k� k� k� k� k� k� jhhb��Ða ahaa"a(k�joehm���5ƒl���haaKk�<write_append tag="id1"> haahaNa‚jhhb��Ða ahaaa&k�joehm���<ƒl���haaKk� <write_append tag="append_reg"> haahaNa‚jhhb��Ða ahaaak�joehm���-ƒl���haa;k� &lt;open id="tag"> ha=a‚jhhb��Ða ahaa ak�joehm���߃l���haa?k� &lt;/open> ha)a*haCaDk�<open id="tag"> haak�Thjis is a writable region haDaDhaJaKk�<write_append id="append_reg"> haahaNa`k�:With the *>* and *&lt;* characters written in column one. haca‚jhhb��Ða ahaaak�rootj�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/previewNewPage.yaws������������������������������������������������0000664�0001750�0001750�00000000264�12605311412�017530� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = previewNewPage, wiki_yaws:call_with_multiquery(wiki, F, Arg). </erl> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/showHistory.yaws���������������������������������������������������0000664�0001750�0001750�00000000254�12605311412�017141� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = showHistory, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/ALockedPage.wob����������������������������������������������������0000664�0001750�0001750�00000001530�12605311412�016500� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ƒhd�wik001k�lockjhhb��Ða a ha a a(k�joekv This is a ''locked'' page - note it has a red border. To edit this page you will need to know the password. ''It's the word *lock*. ''Even though the page as a whole *is* locked you can still change text in the green regions (such as the one below) without knowing the password to the entire page!'' - try clicking on the ''edit'' link below to test this. < aaa bb > l���hm���ƒl���haa k�aaa ha a jhhb��Ða a ha a a(k�joehm���ƒl���haa ha a jhhb��Ða aha aak�joehm���ǃl���k�This page is locked. Note that it has a red border on the left hand side of the page. This is to remind you that it is locked. k� k�1This password of this page is the word ''lock''. haajhhb��Ða ahaaak�joehm���.ƒl���k� This password has password lock k� jhhb��Ða ahaa)a!k�joej������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/deleteFiles.yaws���������������������������������������������������0000664�0001750�0001750�00000000255�12605311412�017025� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = deleteFiles, wiki_yaws:call_with_multi(wiki, F, Arg). </erl> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/editPage.yaws������������������������������������������������������0000664�0001750�0001750�00000000251�12605311412�016316� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = editPage, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/allRefsToMe.yaws���������������������������������������������������0000664�0001750�0001750�00000000252�12605311412�016752� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = allRefsToMe, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/sendMeThePassword.yaws���������������������������������������������0000664�0001750�0001750�00000000262�12605311412�020175� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = sendMeThePassword, wiki_yaws:call_with_multi(wiki, F, Arg). </erl> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/storeNewPage.yaws��������������������������������������������������0000664�0001750�0001750�00000000255�12605311412�017203� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = storeNewPage, wiki_yaws:call_with_multi(wiki, F, Arg). </erl> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/index.yaws���������������������������������������������������������0000664�0001750�0001750�00000000334�12605311412�015705� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(Arg) -> {abs_path, P} = (Arg#arg.req)#http_request.path, Path = yaws_api:url_decode(P), Prefix = wiki_yaws:get_path_prefix(Path), {redirect_local, Prefix ++ "showPage.yaws?node=home"}. </erl> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/thumbIndex.yaws����������������������������������������������������0000664�0001750�0001750�00000000254�12605311412�016706� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = thumbIndex, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/Examples.wob�������������������������������������������������������0000664�0001750�0001750�00000001257�12605311412�016165� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ƒhd�wik002jk�jb@bluetail.comhhb��Ña ahaa a8l���aIadaeanata=l���a{l���k�oka,k�"son.bevemyr.net"ja}jk� jk�J*Exempel* - * ~FormattingWikiPages - * ~ALockedPage - * ~AnUnlockedPage jl���hm���&ƒl���haak�- * ~test_files jhhb��Ña ahaa5a l���aIadaeanata=l���a{l���k�oka,k�"far.bevemyr.net"ja}jk� jhm��� ƒl���haajhhb��Ña ahaa1al���aIadaeanata=l���a{l���k�oka,k�"far.bevemyr.net"ja}jk� jhm���&ƒl���haak�- * ~PWTest k� jhhb��Ña ahaa'a l���aIadaeanata=l���a{l���k�oka,k�"son.bevemyr.net"ja}jk� jhm���ƒl���haak� k� k� jhhb��Ña ahaaal���aIadaeanata=l���a{l���k�oka,k�"son.bevemyr.net"ja}jk� jj�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/wikiZombies.yaws���������������������������������������������������0000664�0001750�0001750�00000000246�12605311412�017074� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = wikiZombies, wiki_yaws:call_wiki(wiki, F, Arg). </erl> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/showPage.yaws������������������������������������������������������0000664�0001750�0001750�00000000252�12605311412�016352� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = showPage, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/putPassword.yaws���������������������������������������������������0000664�0001750�0001750�00000000255�12605311412�017133� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = putPassword, wiki_yaws:call_with_multi(wiki, F, Arg). </erl> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/storeFiles.yaws����������������������������������������������������0000664�0001750�0001750�00000000253�12605311412�016715� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = storeFiles, wiki_yaws:call_with_multi(wiki, F, Arg). </erl> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/www/showOldPage.yaws���������������������������������������������������0000664�0001750�0001750�00000000254�12605311412�017013� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <erl> out(Arg) -> F = showOldPage, wiki_yaws:call_with_query(wiki, F, Arg). </erl> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/scripts/���������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312014�014613� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/scripts/importFiles.in�������������������������������������������������0000664�0001750�0001750�00000000366�12605311412�017366� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash -- progname=`basename $0` localstatedir=@localstatedir@ function usage () { cat <<EOF usage: $progname <wob file> EOF exit 1 } if test $# -ne 1 ; then usage fi erl -noinput -pa @appsdir@/wiki/ebin -s wiki importFiles $1 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/scripts/addFile.in�����������������������������������������������������0000664�0001750�0001750�00000000365�12605311412�016420� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash -- progname=`basename $0` localstatedir=@localstatedir@ function usage () { cat <<EOF usage: $progname <wob file> EOF exit 1 } if test $# -ne 2 ; then usage fi erl -noinput -pa @appsdir@/wiki/ebin -s wiki addFile $1 $2 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/scripts/updateWiki.in��������������������������������������������������0000664�0001750�0001750�00000003021�12605311412�017166� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash -- # -*- Shell-script -*- # File: updateWiki.sh # Author: Johan Bevemyr # Created: Fri May 16 22:06:00 2003 # Purpose: Update existing Wiki installations progname=`basename $0` function usage () { cat <<EOF usage: $progname [directories] EOF exit 1 } wikisrc=@top_srcdir@/applications/wiki/www suffix="."`date -I` updategifs= while [ x$updategifs = x ]; do echo echo -n "Do you want to replace the gifs in WikiPreferences.files?"\ "(yes or no) [no] " read reply leftover case $reply in y* | Y*) updategifs=1 ;; n* | N*) updategifs=0 ;; esac if [ x$reply = x ] ; then updategifs=0 fi done function updateDir () { if test -d $udir ; then echo "updating $udir" install -b -S $suffix $wikisrc/*.yaws $udir install -b -S $suffix $wikisrc/*.wob $udir if test '!' -d $udir/WikiPreferences.files ; then mkdir $udir/WikiPreferences.files fi install -b -S $suffix $wikisrc/WikiPreferences.files/*.css \ $udir/WikiPreferences.files install -b -S $suffix $wikisrc/WikiPreferences.files/*.html \ $udir/WikiPreferences.files if [ $updategifs = 1 ]; then install -b -S $suffix $wikisrc/WikiPreferences.files/*.gif \ $udir/WikiPreferences.files install -b -S $suffix $wikisrc/WikiPreferences.files/*.png \ $udir/WikiPreferences.files fi else echo "$progname: $udir is not a directory" usage fi } if test $# -lt 1 ; then usage fi while test $# -gt 0 ; do udir=$1 shift 1 updateDir done ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/scripts/getPassword.in�������������������������������������������������0000664�0001750�0001750�00000000366�12605311412�017373� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash -- progname=`basename $0` localstatedir=@localstatedir@ function usage () { cat <<EOF usage: $progname <wob file> EOF exit 1 } if test $# -ne 1 ; then usage fi erl -noinput -pa @appsdir@/wiki/ebin -s wiki getPassword $1 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/wiki/Makefile.am������������������������������������������������������������0000664�0001750�0001750�00000000472�12605311412�015104� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������SUBDIRS = src ebin EXTRA_DIST = wiki.conf start.sh README www INSTDIR=$(DESTDIR)$(appsdir)/wiki install-data-local: $(AM_V_at)$(INSTALL) -d $(INSTDIR) $(AM_V_at)(cd @srcdir@; tar cf - www ) | (cd $(INSTDIR); tar xf - ) $(AM_V_at)chmod -R u+rw $(INSTDIR)/www uninstall-local: $(AM_V_at)rm -fr $(INSTDIR)/www ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12605312015�013077� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/Makefile.in������������������������������������������������������������0000664�0001750�0001750�00000051745�12605311445�015110� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/chat DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ SUBDIRS = src ebin INSTDIR = $(DESTDIR)$(appsdir)/chat EXTRA_DIST = www all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/chat/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/chat/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local 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 installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-local install-data-local: $(AM_V_at)$(INSTALL) -d $(INSTDIR) $(AM_V_at)(cd @srcdir@; tar cf - www ) | (cd $(INSTDIR); tar xf - ) $(AM_V_at)chmod -R u+rw $(INSTDIR)/www uninstall-local: $(AM_V_at)rm -fr $(INSTDIR)/www # Local Variables: # tab-width: 8 # End: # 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: ���������������������������yaws-2.0.2/applications/chat/ebin/������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312015�014016� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/ebin/Makefile.in�������������������������������������������������������0000664�0001750�0001750�00000041270�12605311445�016015� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/chat/ebin DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(beamdir)" DATA = $(beam_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ beamdir = $(appsdir)/chat/ebin BEAM_FILES = *.beam beam_DATA = $(BEAM_FILES) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/chat/ebin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/chat/ebin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-beamDATA: $(beam_DATA) @$(NORMAL_INSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(beamdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(beamdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(beamdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(beamdir)" || exit $$?; \ done uninstall-beamDATA: @$(NORMAL_UNINSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(beamdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(beamdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-beamDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-beamDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-beamDATA install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-beamDATA clean-local: $(AM_V_at)rm -f $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: # 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: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/ebin/Makefile.am�������������������������������������������������������0000664�0001750�0001750�00000000252�12605311412�015771� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������beamdir = $(appsdir)/chat/ebin BEAM_FILES = *.beam beam_DATA = $(BEAM_FILES) clean-local: $(AM_V_at)rm -f $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/src/�������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312015�013670� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/src/Makefile.in��������������������������������������������������������0000664�0001750�0001750�00000035754�12605311445�015701� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/chat/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = chat.erl EXTRA_DIST = $(MODULES) EBIN_DIR = @builddir@/../ebin EBIN_FILES = $(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/chat/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/chat/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) clean-local: $(AM_V_at)rm -f $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: ��������������������yaws-2.0.2/applications/chat/src/chat.erl�����������������������������������������������������������0000664�0001750�0001750�00000024675�12605311412�015251� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������% -*- Erlang -*- % File: chat.erl (chat.erl) % Author: Johan Bevemyr % Created: Thu Nov 18 21:27:41 2004 % Purpose: -module('chat'). -author('jb@son.bevemyr.com'). -define(COLOR1, "#ffc197"). -define(COLOR2, "#ff6600"). -define(COLOR3, "#887da7"). -define(COLOR4, "#afa2d3"). -define(LOCATION, "test"). %% There is a bug in the erlang inet driver which causes yaws %% to ignore requests after a POST. This bug is present in the %% now current release R10B-3. We have submitted a bugfix to %% erlbugs so it may be fixed in some future release. Until then... -define(ERL_BUG, true). -export([check_session/1, get_user/1, login/2, chat_server_init/0, session_server/0,dynamic_headers/0, display_login/2]). -export([chat_read/1, chat_write/1]). -include("../../../include/yaws_api.hrl"). -record(user, {last_read, buffer=[], user, pid, color, cookie}). login(User, _Password) -> session_server(), erlang:send(chat_server, {new_session, User, self()}), receive {session_manager, Cookie, _Session} -> chat_server ! {join_message, User}, {ok, Cookie}; _ -> error end. %% FIXME: way to simple session handling. The system will behave %% very badly if two users log in with the same user name!!! check_session(A) -> H = A#arg.headers, case yaws_api:find_cookie_val("sessionid", H#headers.cookie) of [] -> display_login(A, "not logged in"); CVal -> case check_cookie(CVal) of error -> display_login(A, "not logged in"); Session -> {ok, Session} end end. check_cookie(Cookie) -> session_server(), chat_server ! {get_session, Cookie, self()}, receive {session_manager, {ok, Session}} -> Session; {session_manager, error} -> error end. get_user(Session) -> Session#user.user. display_login(_A, Status) -> (dynamic_headers() ++ [{ehtml, [{body, [{onload,"document.f.user.focus();"},{bgcolor,?COLOR3}], [{table, [{border,0},{bgcolor,?COLOR2},{cellspacing,1}, {width,"100%"}], {tr,[{bgcolor,?COLOR1},{height,30}], {td,[{nowrap,true},{align,left},{valign,middle}], {b,[], {font, [{size,4},{color,black}], ["Chat at ", ?LOCATION]}}}}}, {pre_html, io_lib:format("<p>Your login status is: ~s</p>", [Status])}, {form, [{method,post}, {name,f}, {action, "login.yaws"}, {autocomplete,"off"}], {table,[{cellspacing, "5"}], [{tr, [], [{td, [], {p, [], "Username:"}}, {td, [], {input, [{name, user}, {type, text}, {size, "20"}]}} ]}, {tr, [], [{td, [], {p, [], "Password:"}}, {td, [], {input, [{name, password}, {type, password}, {size, "20"}]}}]}, {tr, [], {td, [{align, "right"}, {colspan, "2"}], {input, [{type, submit}, {value, "Login"}]}}} ]}}] }] }]). session_server() -> case whereis(chat_server) of undefined -> Pid = proc_lib:spawn(?MODULE, chat_server_init, []), register(chat_server, Pid); _ -> done end. %% chat_server_init() -> process_flag(trap_exit, true), io:format("Starting chat server\n"), put(color_idx, 0), chat_server([]). %% chat_server(Users0) -> Users = gc_users(Users0), %% io:format("Users = ~p\n", [Users]), receive {get_session, Cookie, From} -> %% io:format("get_session ~p\n", [Cookie]), case lists:keysearch(Cookie, #user.cookie, Users) of {value, Session} -> From ! {session_manager, {ok, Session}}; false -> From ! {session_manager, error} end, chat_server(Users); {new_session, User, From} -> Cookie = integer_to_list(bin2int(crypto:rand_bytes(16))), Session = #user{cookie=Cookie, user=User, color=pick_color()}, From ! {session_manager, Cookie, Session}, chat_server([Session|Users]); {write, Session, Msg} -> NewUsers = send_to_all(msg, fmt_msg(Session#user.user, Msg, Session#user.color), Users), chat_server(NewUsers); {send_to, User, Msg} -> NewUsers = send_to_one(msg, Msg, Users, User), chat_server(NewUsers); {join_message, User} -> NewUsers0 = send_to_all(msg,fmt_join(User), Users), NewUsers1 = send_to_all(members, fmt_members(NewUsers0), NewUsers0), chat_server(NewUsers1); {members, User} -> NewUsers1 = send_to_one(members, fmt_members(Users), Users, User), chat_server(NewUsers1); {left_message, User} -> NewUsers0 = send_to_all(msg,fmt_left(User), Users), NewUsers1 = send_to_all(members, fmt_members(NewUsers0), NewUsers0), chat_server(NewUsers1); {read, Session, Pid} -> %% io:format("~p want read ~p\n", [Session#user.user, Pid]), NewUsers = user_read(Users, Session, Pid), chat_server(NewUsers); {cancel_read, Pid} -> NewUsers = cancel_read(Users, Pid), chat_server(NewUsers) after 5000 -> chat_server(Users) end. bin2int(Bin) -> lists:foldl(fun(N, Acc) -> Acc * 256 + N end, 0, binary_to_list(Bin)). %% cancel_read([], _Pid) -> []; cancel_read([U|Us], Pid) when U#user.pid == Pid -> Now = inow(now()), [U#user{pid=undefined,last_read=Now}|Us]; cancel_read([U|Us], Pid) -> [U|cancel_read(Us, Pid)]. %% user_read(Users, User, Pid) -> user_read(Users, User, Pid, Users). user_read([], _User, _Pid, All) -> All; user_read([U|Users], User, Pid, _All) when U#user.cookie == User#user.cookie -> if U#user.buffer /= [] -> Pid ! {msgs,lists:reverse(U#user.buffer)}, [U#user{buffer=[]}|Users]; true -> [U#user{pid=Pid}|Users] end; user_read([U|Users], User, Pid, All) -> [U|user_read(Users, User, Pid, All)]. %% send_to_all(Type, Msg, Users) -> Now = inow(now()), F = fun(U) -> if U#user.pid /= undefined -> %% io:format("Sending ~p to ~p\n", [Msg, U#user.user]), U#user.pid ! {msgs, [{Type, Msg}]}, U#user{pid=undefined, last_read = Now}; true -> U#user{buffer=[{Type,Msg}|U#user.buffer]} end end, lists:map(F, Users). %% send_to_one(Type, Msg, Users, User) -> Now = inow(now()), F = fun(U) when U#user.cookie == User#user.cookie -> if U#user.pid /= undefined -> %% io:format("Sending ~p to ~p\n", [Msg, U#user.user]), U#user.pid ! {msgs, [{Type, Msg}]}, U#user{pid=undefined, last_read = Now}; true -> U#user{buffer=[{Type,Msg}|U#user.buffer]} end; (U) -> U end, lists:map(F, Users). %% gc_users(Users) -> Now = inow(now()), gc_users(Users, Now). gc_users([], _Now) -> []; gc_users([U|Us], Now) -> if U#user.pid == undefined, (Now-U#user.last_read > 10) -> self() ! {left_message, U#user.user}, gc_users(Us, Now); true -> [U|gc_users(Us, Now)] end. % inow(Now) -> {MSec, Sec, _} = Now, MSec*1000000 + Sec. % dynamic_headers() -> [yaws_api:set_content_type("text/html"), {header, {cache_control, "no-cache"}}, {header, "Expires: -1"}]. % chat_read(A) -> session_server(), case check_session(A) of {ok, Session} -> chat_server ! {read, Session, self()}, if length(A#arg.querydata) > 0 -> chat_server ! {members, Session}; true -> ok end, receive {msgs, Messages} -> M = [fmt_type(Type,L) || {Type, L} <- Messages], dynamic_headers()++[{html, ["ok",M]}, break] after 20000 -> catch erlang:send(chat_server, {cancel_read, self()}), dynamic_headers()++[{html, "timeout"}, break] end; _Error -> dynamic_headers()++[{html, "error"}, break] end. type2tag(msg) -> $m; type2tag(members) -> $e. % fmt_type(Type, L) -> Data = list_to_binary(L), [type2tag(Type), integer_to_list(size(Data)),":", Data]. % -ifdef(ERL_BUG). chat_write(A) -> session_server(), case check_session(A) of {ok, Session} -> chat_server ! {write, Session, A#arg.clidata}, [{html, "ok"}, break]; Error -> Error end. -else. chat_write(A) -> session_server(), case check_session(A) of {ok, Session} -> chat_server ! {write, Session,A#arg.clidata}, [{header, {connection,"close"}}, {html, "ok"}, break]; Error -> Error end. -endif. %% fmt_join(User) -> ["<strong>",date_str()," ",User, " joined</strong>"]. %% fmt_left(User) -> ["<strong>",date_str()," ",User," left</strong>"]. %% fmt_msg(User, Msg, Color) -> ["<font color=",Color,">",date_str()," <strong>",User,":</strong></font> ", Msg]. %% fmt_members(Users) -> [[U#user.user,"<br>"] || U <- Users]. %% date_str() -> {_,{H,M,S}} = calendar:local_time(), io_lib:format("<small>(~2.2.0w:~2.2.0w:~2.2.0w)</small>", [H,M,S]). %% pick_color() -> Nr = get(color_idx), put(color_idx, (Nr+1) rem 4), colors(Nr). %% colors(0) -> "blue"; colors(1) -> "orange"; colors(2) -> "red"; colors(3) -> "green". �������������������������������������������������������������������yaws-2.0.2/applications/chat/src/Makefile.am��������������������������������������������������������0000664�0001750�0001750�00000001061�12605311412�015642� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include @top_srcdir@/include.mk MODULES = chat.erl EXTRA_DIST = $(MODULES) EBIN_DIR=@builddir@/../ebin EBIN_FILES=$(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) clean-local: $(AM_V_at)rm -f $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/�������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�013725� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/kiss.png�����������������������������������������������������������0000664�0001750�0001750�00000000600�12605311412�015320� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ /ÀÚÕP�� IDATxœ•TÙ­Ä VÛ‘©ÉÔDjÂ5Íû ŽÕ³d%ò1>qÀžxÐ…•ð³a)�9s)Í!X5*$s)3 O—<Å2÷/ <8­LÞéìþ^×£re?=k†0Ç]'ˆ ˆ Hר—åÇg#âX�\&=˜™@uÔûìzSUµ5•¼‘3H²ëDd9�œV£OAFy®¨‘·ËPæD9çþ/¤”¶�«d*—ZjÎs)ªJUÝîÝÔ3ž¶œõ½gæÇgxV9�ˆ¯:Þ£vþÍlKûvîÍX�ݳh¯à»q©‡u ¶6©Ùq!õ™­b,Þf•‡»þæ¨Ø³hGížý:=Sˆê¿/íò|$°=yŒ����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/scream.png���������������������������������������������������������0000664�0001750�0001750�00000000507�12605311412�015627� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ +nÚÓ���ÔIDATxœ¥T[à \2¹‘wÊ̙șè‡EQ¶Óay¬ë B Ibä9€D˜‘ݘGN2YKb†ˆ@JißÕÔÏœöý_ u¼æ†ŠD µB,aC‹Ç 7¢æ…‘ߪ;t³ÿÊ �¥ŒÀuD„&Âߨ>­§w|‘ç>;#é^A ¶#$[Õ|Cæ½€ŽûÎǦ;f ØÍËÓ»¦‹Haš9Σ¾ÌçÙ“jÍÇkû£ºL0�í mûYY¢ÚÏÒ͆Ó-2ÖŸ;í ‰(ú‰1ó»����IEND®B`‚�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/login.yaws���������������������������������������������������������0000664�0001750�0001750�00000001343�12605311412�015663� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> L = case (A#arg.req)#http_request.method of 'GET' -> yaws_api:parse_query(A); 'POST' -> yaws_api:parse_post(A) end, case {lists:keysearch("user", 1, L), lists:keysearch("password", 1, L)} of {{value, {_, User}}, {value, {_,Passwd}}} -> case chat:login(User, Passwd) of {ok, Cookie} -> [yaws_api:setcookie("sessionid", Cookie), {redirect_local, {rel_path,"chat.yaws"}}]; {error, Reason} -> chat:display_login(A, Reason) end; _ -> chat:display_login(A, "badly formated POST/GET") end. </erl> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/chat.yaws����������������������������������������������������������0000664�0001750�0001750�00000003306�12605311412�015473� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <erl> out(A) -> case chat:check_session(A) of {ok, Session} -> chat:dynamic_headers(); Error -> Error++[break] end. </erl> <script> function handleEnter(event) { if (event == null) event = window.event; var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode; if (keyCode == 13) { sendmsg(); return false; } } function addSmiley(ref) { var text = document.getElementById("msg"); text.value = text.value+"<img src='"+ref+"'>"; text.focus(); return false; } function addText(ref) { var text = document.getElementById("msg"); text.value = text.value+ref; text.focus(); return false; } </script> <style> body { font: 10px/15px Verdana, Lucida, Arial, sans-serif; } h1 { font: 15px/20px Verdana, Lucida, Arial, sans-serif; font-weight: bold; } #msgs { border:1px solid #ccc; height: 25em; width: 500px; background-color: #f5f5ff; overflow: auto; float: left; padding: 2px; } #members { border:1px solid #ccc; height: 25em; width: 100px; background-color: #f5f5ff; overflow: auto; margin: 2px; padding: 2px; } #msg { width: 614px; clear: both; } </style> <script src="chat.js"></script> <body onload="setTimeout('reader_init0()', 0);" onunload="stop_all()"> <H1> Welcome to the chat room </h1> <div id="msgs"></div> <div id="members"></div> <textarea id="msg" rows="3" value="" onKeyPress="return handleEnter(event)"> </textarea> <br> <script> document.write(smilies_toolbar()); </script> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/sad.png������������������������������������������������������������0000664�0001750�0001750�00000000552�12605311412�015124� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ  ~©Ø���÷IDATxœSÛ! sNÛÔÄÖ”žBM¾.¼3»:K‘“&‚|Ø“ùˆÐ Ï09‡µ$3lŒï}mv ÎvÉiK¤99úÛx‘¡ãmòÏ>D€œRJÈ9-B΋t‘¹íÅI°°”B‡Yê¼CÕ×£}wÖ]€êܸ…ZWnΛÝ-—¼]nwf–&î¬ ÅF[g¨Þy�l¯ø_ˆ�¯§ÍÑá˼ßCHõ>ªã Ï_Äü¥� çVTJ[ךz�'[žc®oÎ?\üÓaÿioÏýMÌ3Îæ·¸Ífãåì?B­«P„ð/ß§ãpùA4µî\Ép^³‡����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/farted.png���������������������������������������������������������0000664�0001750�0001750�00000000571�12605311412�015623� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ Ãó¥ü��IDATxœ•TÉÄ “Óùo7ô”­ÉüÓöÁe0$³ža|!ËÁ^ø`“•òØ$¡*@ú¥Ú}ËNª ù¾T}B —|=Ë‹HÏSËd?;í‚›˜²²•Hæç Íì@�¼ïÏ`ˆ1@Ä£¨ºj_¡k¤`ŒÌ8ÍÓžŒ1pŽ®Æ¿ Xùm׎b…¬é¦+€‚J~šø9ýé•'Ú·nóò¢ú2È’(™Ã ˆ�ÒÂ0ìtå?M~™yµ1q¼Píê1E·(3�×@ͼջ%’÷Ôl¯\YgsAìRLY¥QÃl€ÈYü,_³L²4%ÚI}ÏÞžweŸ²þýÒþ�ih‚ê·56����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/think.png����������������������������������������������������������0000664�0001750�0001750�00000000543�12605311412�015472� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ 2‘êÛ ���ðIDATxœTÛ ! sªn”Ì3ÝN¹™ÜÊ›£¢–"Ý…`ìD x7k²J¾Hès¸×šÍa©È$S�õ{üwŸ [¹d³$’”Lþ†¼HåÉ6ù•‘ª 3íˆÌªZj€Îv§Š�˜¡ªÅV¡ä¯+×Õ}�ðnU‘@Œá«p9°’o­ºf‰°krÓØ¡áJUò£ºi!“žäPÆ)ž ¬HêÙ_$+¬nÀ„³DbÖ߈Ë>„0á)òв`¶ÞSâØ¶›÷]INˆò>`s7OUý�D¤?é—¢–è ù=Û6‹÷lÇzüÒ~�F—8þâDH§����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/embarrassed.png����������������������������������������������������0000664�0001750�0001750�00000000564�12605311412�016650� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ ݃ËU��IDATxœ•TÉÃ0\Üþ§õ”Ô„ÿéfóÐa$$%a†±Í±Z@F°n|23 šdT³;fsX2Éïj=]òëYQDnœZ& ý1h•Üĕݘu¬DrvlÆx�r�àûýè))D"‹j«þ»ÖT�LIÉÌÓ=1|“))ÇÜîjü;€Y|?v»Y̘5Ûp…�PP› ý9ãéµOô“×Ûÿ€++-–A ËîH�pM]ÂÊVÞkþ@γ§ü³”ø’/±L^P@sßêÝ)}tþä ¨ŠîSó±Øl¼5žàéÔÙf[c Ø@÷«'�-vC]É4ïS‚#œ·æ8]����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/smile.png����������������������������������������������������������0000664�0001750�0001750�00000000464�12605311412�015470� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ  3‡���ÁIDATxœTÛ![ڞܚ¶'¬‰û¸C‘‡º—bˆaDrðb#²$&LÀìÑÐ,ûŠˆ€™÷‹Èê¸ÌÛ³<‡´É¿øV”w¨¶{²)•.xÁc‰R½…¤C›êŸd²FÚ‚Œ„f«‚Õ;³ìOtÅ j=3«56tSqvò#.œ3ÝÆó î¾Ej{Î0 �0_cÙDönßæj¶lª2ñÐÚ,ÖßFk¾½G ­M)7¦ºt*âi`Ýß����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/cry.png������������������������������������������������������������0000664�0001750�0001750�00000000536�12605311412�015154� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ #ûZûù���ëIDATxœ•TíÅ ‹½·ɺΔ÷CmE¡Þy­c@0!¼ñ%ϸ$TÈuª^˜›Ã*H$Ÿ§êJ8Ê%§³RªjÆu.¶4†É&ÿì»ÝÔIÈ‹0aU$«t‘Æéë¶þ÷„y:5ès“g›ó·€ÜA29I"g‹!îm‰E„ªbl9çöoñ=ÔW¥0O�ÌÙ®ëm?̯ã9’Û0=/kÙ„ds±>ùK‹¬ŸO*�iÀ±€w«È#ì]°(3ŠÊ@,>®ù&_6¹W1á RïÕp ©†$ ÑM|iÿ~f{6½ëÊ����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/chat_write.yaws����������������������������������������������������0000664�0001750�0001750�00000000264�12605311412�016705� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case chat:check_session(A) of Session -> chat:chat_write(A); Error -> Error end. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/burp.png�����������������������������������������������������������0000664�0001750�0001750�00000000527�12605311412�015327� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ ^PN’���äIDATxœ”Ñ Ä †ºÎÔÎdg™¸ÏŠ 6w$$À•‹nläDE�ÕUEºÏ&Yuª¾«È ´åª¾æZ…¨sZ›ú-�RUOf›i{¨JU¡Ìµ‘úm[‹l vÌUŒû>‘PÊXóùØ�v«[²7ñ*‹l.¬ñâl̼œPŸSœ…È_ÚPJ®«{ŸûX5gçÎÎstzµ˜y�ÐËì)s­¨ É‚†V›ÓÖ×ć ÀYíä·7¿K?­‰ýÉ=Z¦”zÔリñ¼Ã&’€îzãé����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/bigsmile.png�������������������������������������������������������0000664�0001750�0001750�00000000500�12605311412�016141� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ  {H›���ÍIDATxœ•TmÅ ƒå݈û߀©ûáÃŒ&dFJ-Ê”9ŽŸ„ªDÀªSlÖ@ªàª;á,8îµæÁcmâ/Ÿ˜×ð…>7µ½¨‚ˆù%Pk@oiɉ,¹á“ÝÆ\Ïæ•ɾñm®avGÀæSEäÿXtÎŽ„Yþ-6…9c–_”y€¹ìçþ!"zßQ|3 oõFJ~E6á¹·©:dG­ù9QÃÛÍÙ6‡ý›Íi½5á)¢W#$4ðáéÙˆ*·¯_ÚÒ|­z_ª����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/cool.png�����������������������������������������������������������0000664�0001750�0001750�00000000464�12605311412�015313� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ µ‘���ÁIDATxœ•TËD! ÎvdQ¯&{šØÃ®Oðà C@#!6YÄÈÛLˆ0"Ö™{΢Ø/‰"²wf ¨éŠlkY#ê8­MùÓ¿6ÕöË,ä¤Ù’;öNPÃv3¨{T¬±#¨Ym*‡`íìç4ù¤ØðÎæVo׆Ùîy¬âF§sóò�Ôz4¶óÍ©�R²+£R²xùجI öH£Km¥äwý<Õ\€ÖælK†»_Ãô@´º¿ëŸö d åáxY§����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/yell.png�����������������������������������������������������������0000664�0001750�0001750�00000000477�12605311412�015330� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ z-Ç���ÌIDATxœ•”ÁÄ E?™t¤5mQ[ÖÄ"‰Q@Öþƒ #Á?ÄÈrD˜‘Õ˜Ÿœ Ø•Ä Ùs  R+å <‡Ž®aôiH𚣚Z!ƒ2‹-¨W¨ûé»Ú‰ô›¦»ÔK¡lW™îÎ5=žW3aV'˜µ´.Èóma‘È‹�К/ÌÕo÷ �ŠŠ†¸±t_@k@)XŽ|¦"_»+à™Õ:A†Ê­½Ec¬ëÌ).¯�)Ý€ü«q-¨Y@ÁüÿÒþ�ÍÓÈÊÛ–a����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/crossedlips.png����������������������������������������������������0000664�0001750�0001750�00000000450�12605311412�016704� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ ©Eÿ���µIDATxœ¥TËÃ0Y)ûo@f¢—\áO£÷|Á  "¨aƒ;aÁ£ 1UÀì÷¨>9ƒf-If6?ªc”|žœ¤3¤(|+Lñ¨P‚ªžw#.ÇWÕ+¸)Ò«ŠÝvãl4Z›Â§* Èþ%ɽzGÉÜ/¼®L22¬œú0C¶˜×g$@›~FŠn è0ýÛ�W· Ÿ~  þØ+pSPüÛn…X7%«œV uÓ=,½ /.D����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/wink.png�����������������������������������������������������������0000664�0001750�0001750�00000000471�12605311412�015325� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ  ý,���ÆIDATxœµTA!#þÈÿÿ€}Sz@\\Qkgš‹®@æàâ ™ó5!¡ª9šê³(fAªBroª#a”Knk�no“Uþ1BÛ*’ÂRLþ7­ºE²6'#1d„5i:?H˜`¨ƒˆþ»…ùì:²˜xz€ÈûéüåFÙOû2¤(!»®}Y‡Œ1®å·ØîFçÊghm:ûS[)9‘çEeº¨$¶™!{›æG¯0Z¦(Íàûl·z†+ÖãMû¿eãà–"öz����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/index.yaws���������������������������������������������������������0000664�0001750�0001750�00000000112�12605311412�015653� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> {redirect_local, {rel_path, "chat.yaws"}}. </erl> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/moneymouth.png�����������������������������������������������������0000664�0001750�0001750�00000000453�12605311412�016561� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ 0TÉéä���¸IDATxœ­T[Ã0ƒj÷?9“ûÑÑBx¤™f)RÄØ†ÂT3ãQ@„ˆGä‰iŠ]A"`}D"¡• ,kE0?<Ú&¾òç *ù†iûVæTÙ„ ;™ª]¨:žUý¢L}ÙhÜsBeW¤d]B÷â%‘o‹¹~á”lNVzbL #WðænóÝœejÞÜuÎ>–Ý~\ÛRF¤v×YߟþÍËξR‡1<QÝg«ÕúèX·7í ŸžuuI{Ø����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/tongue.png���������������������������������������������������������0000664�0001750�0001750�00000000470�12605311412�015655� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ  0ÏÉ@ü���ÅIDATxœTÛÄ „´djºž®'¬iïà =à á±ìަÜ0Éq<ˆÞEFÍdX+!�kñ€š.°œåyàt™¸èÛ¢¬ù6%ûfö`¥6â|D¬v­³cËê ³ž‹Vãµ…`}ªžÅC°óôÙ [?ò ”Ò±”ÿ–ÖÖÓµnëW€6߯!ܳLB7©DõKT>í[_AÈÎyt÷æF÷nóQíYé×df¢Z'`^«——¶d²•,§c†ºý§ýÕOEY,)����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/chat.js������������������������������������������������������������0000664�0001750�0001750�00000011364�12605311412�015127� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- Fundamental -*- // File: chat.js (/var/www/chat.js) // Author: Johan Bevemyr // Created: Thu Nov 18 18:25:53 2004 // Purpose: // Uncomment this to get debug printouts in a separate window. /* var _console=null; var _console_txt = null; var _cnt = 0; function debug(msg) { var re = new RegExp("<","gi"); msg = msg.replace(re, "&lt;") if ((_console==null) || (_console.closed)) { _console = window.open("","console","width=600,height=300,resizable=yes,scrollbars=yes"); _console.document.open("text/plain"); _console.document.writeln("<pre>"); } _cnt++; _console.document.write(_cnt + ": "); _console.document.writeln(msg); } */ function debug(msg) { } function sendmsg() { var message = document.getElementById("msg").value; debug("sendmsg: sending "+message); xml_sender.abort(); xml_sender.open("POST", "chat_write.yaws", false); message = expandSmilies(message); xml_sender.send(message); debug("sendmsg: sent "+message); document.getElementById("msg").value = ""; } var smilies = new Array(); smilies[":-)~"] = "tongue.png"; smilies["O :-)"] = "angel.png"; smilies[":-)"] = "smile.png"; smilies[":-("] = "sad.png"; smilies[":-D"] = "bigsmile.png"; smilies[":-?"] = "burp.png"; smilies["8-)"] = "cool.png"; smilies[":-X"] = "crossedlips.png"; smilies[":,-("] = "cry.png"; smilies[":-6"] = "farted.png"; smilies[":*"] = "kiss.png"; smilies[":-$"] = "moneymouth.png"; smilies["0-)"] = "oneeye.png"; smilies[":-@"] = "scream.png"; smilies[":-/"] = "think.png"; smilies[",-)"] = "wink.png"; smilies[":O"] = "yell.png"; function smilies_toolbar() { var tool=""; var smile; for (smile in smilies) { tool += ("<img src='"+smilies[smile]+"' onmousedown='return addText(\""+ smile+"\")'></img> "); } return tool; } function expandSmilies(message) { var smile; for (smile in smilies) { var i = 0; i = message.indexOf(smile,i); while(i >= 0) { message = message.substring(0,i)+"<img src='"+smilies[smile]+"'>"+ message.substring(i+smile.length); i = message.indexOf(smile,i); } } return message; } function create_xmlhttp() { var xmlhttp; try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xmlhttp = false; } } if (!xmlhttp && typeof XMLHttpRequest!='undefined') xmlhttp = new XMLHttpRequest(); return xmlhttp; } var xml_sender = create_xmlhttp(); var xml_reader = create_xmlhttp(); var intialized = false; function reader_init0() { initialized = false; reader_init(); } function reader_init() { var h = function() { debug("reader_init(): got " + xml_reader.readyState); if (xml_reader.readyState == 4) { var msgs = document.getElementById("msgs"); var memb = document.getElementById("members"); var reply = xml_reader.responseText; debug("reader_init(): something"); if (reply.substring(0,2) == "ok") { var msg = reply.substring(2); var messages = ""; var members = ""; while(msg.length > 0) { var op = msg.substring(0,1); var i = msg.indexOf(":"); var len = parseInt(msg.substring(1,i)); var body = msg.substring(i+1, i+len+1); msg = msg.substring(i+len+1); debug("msg = " + msg); debug("i = " + i); debug("len = " + len); debug("body = " + body); debug("op = " + op); switch(op) { case "m": messages += body.replace(/\n/g,"<br>")+"<br>"; break; case "e": members = body; break; default: } } if (messages.length > 0) msgs.innerHTML = msgs.innerHTML + messages; if (members.length > 0) memb.innerHTML = members; move_to_end(msgs); setTimeout("reader_init()", 0); } else if (reply.substring(0,7) == "timeout") { setTimeout("reader_init()", 0); } else { // alert("Chat server got unsupported reply.'" + reply+"'"); } } } debug("reader_init(): waiting"); if (initialized) { xml_reader.open("GET", "chat_read.yaws", true); } else { xml_reader.open("GET", "chat_read.yaws?init=true", true); initialized = true; } if (window.XMLHttpRequest) { xml_reader.onload=h; } else { xml_reader.onreadystatechange=h; } xml_reader.send(null); debug("reader_init: sent read request"); } function move_to_end(element) { try { element.scrollTop = element.scrollHeight; } catch(E) { } } function stop_all() { try { xml_reader.abort(); } catch (E) { } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/angel.png����������������������������������������������������������0000664�0001750�0001750�00000000461�12605311412�015442� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ /ë÷†“���¾IDATxœ•”Û„0Ea[šRTšÅe—ÇWft A&(K±>Ëf¿âhôlSÂË—«1@º a7 %"ÒÅ?TˆGZ†.J•e ‘ê~�-·*=#µŠ¢c/–ð.‰£Mã#"E‡üèî1;ØŠgé?ÝŽCJ¤óÒÂLPð4û_=C:ëÛØ³7â{Æ~â®oy 6 8gf™ŽøÃùT ú¾&à$yò»;ëå­1ÃñòÁ§£‡ôœ×����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/chat_read.yaws�����������������������������������������������������0000664�0001750�0001750�00000000062�12605311412�016462� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> chat:chat_read(A). </erl> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/www/oneeye.png���������������������������������������������������������0000664�0001750�0001750�00000000446�12605311412�015643� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���������rP6Ì���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� ÒÝ~ü���tIMEÒ 3.ÕBI���³IDATxœ­”Qƒ@DgLoÔÞÿí™èÇfq†m›’˜( QÂ[4güÔ� ŠGÖ)¿Â¢ƒèÎȰ¯@ 8aD1„&Ž·®¢ª@ÒΓJUñ‘T==6§ì“ʪº³_·Ivf#Qù]`CÑ:1ÇMÛVΆr› µ[²/—v¥°ž·K»Rè Í6Õ‹CÜÇUï«J”oó(ZÛM�¾t{û³Pû·ÿÙÚØ%÷ ‘,RïspÏ����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/chat/Makefile.am������������������������������������������������������������0000664�0001750�0001750�00000000516�12605311412�015057� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������SUBDIRS = src ebin INSTDIR=$(DESTDIR)$(appsdir)/chat EXTRA_DIST = www install-data-local: $(AM_V_at)$(INSTALL) -d $(INSTDIR) $(AM_V_at)(cd @srcdir@; tar cf - www ) | (cd $(INSTDIR); tar xf - ) $(AM_V_at)chmod -R u+rw $(INSTDIR)/www uninstall-local: $(AM_V_at)rm -fr $(INSTDIR)/www # Local Variables: # tab-width: 8 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12605312016�013103� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/Makefile.in������������������������������������������������������������0000664�0001750�0001750�00000052561�12605311445�015110� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/mail DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README TODO ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ SUBDIRS = src ebin EXTRA_DIST = yaws-webmail.conf TODO README www INSTDIR = $(DESTDIR)$(appsdir)/mail all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/mail/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/mail/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local 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 installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-local install-data-local: $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(sysconfdir)/mail $(AM_V_at)if [ -f $(DESTDIR)$(sysconfdir)/mail/yaws-webmail.conf ]; then \ echo "$(DESTDIR)$(sysconfdir)/mail/yaws-webmail.conf already exists"; \ else \ $(INSTALL) -m 644 @srcdir@/yaws-webmail.conf $(DESTDIR)$(sysconfdir)/mail; \ fi $(AM_V_at)$(INSTALL) -d $(INSTDIR) $(AM_V_at)(cd @srcdir@; tar cf - www ) | (cd $(INSTDIR); tar xf - ) $(AM_V_at)chmod -R u+rw $(INSTDIR)/www uninstall-local: $(AM_V_at)rm -f $(DESTDIR)$(sysconfdir)/mail/yaws-webmail.conf $(INSTDIR)/www # Local Variables: # tab-width: 8 # End: # 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: �����������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/README�����������������������������������������������������������������0000664�0001750�0001750�00000002250�12605311412�013703� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ This is a very basic WebMail application which is completely stateless, by design. I didn't want any SQL databases etc for storing the emails. The reason for building it was that I needed a local WebMail and I didn't want to install an Apache with python or PHP, and besides all those relied on some local store (mbox, MySQL etc) which I didn't want. Also, Klacke told me that he never finished the other webmail app so I started from scratch. A few important things are still missing. The most notable is the ability to handle attached files and email on multipart format... To install ---------- - Yaws should be installed - Run 'make install' - Edit $(etcdir)/mail/yaws-webmail.conf Two things need to be edited in /etc/yaws.conf 1. Yaws must find the beam code for mail.beam. This path must be added to /etc/yaws conf as in: ebin_dir = $(vardir)/yaws/mail/ebin 2. The virtual server that is supposed to run the webmail must have an appmod called 'attachment' installed. Here is an example: <server flinta> port = 80 appmods = attachment listen = 0.0.0.0 docroot = $(vardir)/yaws/mail/www </server> /Johan Bevemyr ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/ebin/������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312016�014022� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/ebin/Makefile.in�������������������������������������������������������0000664�0001750�0001750�00000041270�12605311445�016020� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/mail/ebin DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(beamdir)" DATA = $(beam_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ beamdir = $(appsdir)/mail/ebin BEAM_FILES = *.beam beam_DATA = $(BEAM_FILES) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/mail/ebin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/mail/ebin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-beamDATA: $(beam_DATA) @$(NORMAL_INSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(beamdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(beamdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(beamdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(beamdir)" || exit $$?; \ done uninstall-beamDATA: @$(NORMAL_UNINSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(beamdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(beamdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-beamDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-beamDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-beamDATA install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-beamDATA clean-local: $(AM_V_at)rm -f $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: # 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: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/ebin/Makefile.am�������������������������������������������������������0000664�0001750�0001750�00000000252�12605311412�015774� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������beamdir = $(appsdir)/mail/ebin BEAM_FILES = *.beam beam_DATA = $(BEAM_FILES) clean-local: $(AM_V_at)rm -f $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/src/�������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312016�013674� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/src/Makefile.in��������������������������������������������������������0000664�0001750�0001750�00000036065�12605311445�015700� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/mail/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = mail.erl attachment.erl smtp.erl mail_html.erl EXTRA_DIST = $(MODULES) defs.hrl EBIN_DIR = @builddir@/../ebin EBIN_FILES = $(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -DETCDIR='"@sysconfdir@"' all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/mail/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/mail/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) clean-local: $(AM_V_at)rm -f $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/src/defs.hrl�����������������������������������������������������������0000664�0001750�0001750�00000000777�12605311412�015256� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������% -*- Erlang -*- % File: defs.hrl (/mnt/disk2/jb/work/yaws/yaws/applications/mail/src/defs.hrl) % Author: Johan Bevemyr % Created: Wed Oct 29 23:39:30 2003 % Purpose: -ifndef(DEFS_HRL). -define(DEFS_HRL, true). %% Create config file in /etc/mail/yaws-webmail.conf -record(cfg, {ttl = 1800, % 30 minuter TTL popserver = "localhost", maildomain = "foo.bar", smtpserver = "localhost", sendtimeout = 3000}). -endif. �yaws-2.0.2/applications/mail/src/mail.erl�����������������������������������������������������������0000664�0001750�0001750�00000302032�12605311412�015241� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������% -*- Erlang -*- % File: mail.erl (~jb/mail.erl) % Author: Johan Bevemyr % Created: Sat Oct 25 10:59:24 2003 % Purpose: % RFC 822 % RFC 1939 % RFC 2048 -module('mail'). -author('jb@trut.bluetail.com'). -export([parse_headers/1, list/2, list/3, ploop/5,pop_request/4, diff/2, session_manager_init/0, check_cookie/1, check_session/1, login/2, display_login/2, stat/3, showmail/2, compose/1, compose/7, send/6, send/2, get_val/3, logout/1, base64_2_str/1, retr/4, delete/2, send_attachment/2, send_attachment_plain/2, wrap_text/2, getopt/3, decode/1]). -export([read_config/1]). -include("../../../include/yaws_api.hrl"). -include("defs.hrl"). -record(info, { nr, size, headers }). -record(mail, { from="", from_fmt="", from_fmt_lc="", to="", cc="", bcc="", subject="", subject_fmt="", subject_fmt_lc="", date="", date_pst=date(), date_fmt="", content_type, transfer_encoding, content_disposition, other = [] }). -record(pstate, { port, user, pass, cmd, acc = [], from, lines, reply=[], more=true, remain, dotstate=0 }). -record(satt, { num, filename, ctype, data}). -record(session, { user, passwd, cookie, listing, sorting=rev_nr, attachments = [] %% list of #satt{} records }). -define(RETRYTIMEOUT, 300). -define(RETRYCOUNT, 5). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % build_toolbar(Entries) -> {table, [{bgcolor,"c0c0c0"},{cellpadding,0},{cellspacing,0},{border,0}], [{tr,[],{td, [{colspan,20},{height,1},{bgcolor,white}], {img, [{src,"spacer.gif"}, {width,1},{height,1}, {alt,""}, {border,0}],[]}}}, {tr,[], build_toolbar(Entries, -1)}, {tr,[],{td, [{colspan,20},{height,1},{bgcolor,gray}], {img, [{src,"spacer.gif"}, {width,1},{height,1}, {alt,""}, {border,0}],[]}}}, {tr,[],{td, [{colspan,20},{height,1}], {img, [{src,"spacer.gif"}, {width,1},{height,1}, {alt,""}, {border,0}],[]}}}]}. build_toolbar([], Used) -> Percent = integer_to_list(100-Used)++"%", [{td, [nowrap,{width,Percent},{valign,middle},{align,left}],[]}]; build_toolbar([{[],Url,Cmd}|Rest], Used) -> if Used == -1 -> []; true -> [{td, [nowrap,{width,"1%"},{valign,middle},{align,left}], {img, [{src,"tool-div.gif"},{width,2},{height,16}, {alt,""},{border,0},{hspace,2}]}}] end ++ [{td, [nowrap,{width,"2%"},{valign,middle},{align,left}], [{a, [{class,nolink}, {href,Url}], {font, [{size,2},{color,"#000000"},{title,Cmd}],Cmd}}]} | build_toolbar(Rest, Used+3)]; build_toolbar([{Gif,Url,Cmd}|Rest], Used) -> (if Used == -1 -> []; true -> [{td, [nowrap,{width,"1%"},{valign,middle},{align,left}], {img, [{src,"tool-div.gif"},{width,2},{height,16}, {alt,""},{border,0},{hspace,2}]}}] end ++ [{td, [nowrap,{width,"2%"},{valign,middle},{align,left}], {a, [{class,nolink}, {href,Url}], [{img, [{src,Gif},{vspace,2},{width,20}, {height,20},{alt,Cmd},{border,0}],[]}]} }, {td, [nowrap,{width,"2%"},{valign,middle},{align,left}], [{a, [{class,nolink}, {href,Url}], {font, [{size,2},{color,"#000000"},{title,Cmd}], Cmd}}]} | build_toolbar(Rest, Used+4)]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % delete(Session, ToDelete) -> tick_session(Session#session.cookie), Req = [del(M) || M <- ToDelete], pop_request(Req, popserver(), Session#session.user, Session#session.passwd), {redirect_local, {rel_path, "mail.yaws?refresh=true"}}. -record(send, {param, last = false, encoding, estate="", boundary="", from="", to="", cc="", bcc="", subject="", message="", attached="", port, session, line_start=true }). send(Session, A) -> State = prepare_send_state(A#arg.state, Session), case yaws_api:parse_multipart_post(A) of {cont, Cont, Res} -> case catch sendChunk(Res, State) of {done, Result} -> Result; {cont, NewState} -> {get_more, Cont, NewState}; {error, Reason} -> {ehtml, format_error("Failed to send email. Reason: "++ to_string(Reason))} end; {result, Res} -> case catch sendChunk(Res, State#send{last=true}) of {done, Result} -> Result; {cont, _} -> {ehtml,format_error("Failed to send email.")}; {error, Reason} -> {ehtml, format_error("Failed to send email. Reason: "++ to_string(Reason))} end end. prepare_send_state(undefined, Session) -> #send{session=Session}; prepare_send_state(State, Session) -> State#send{session=Session}. sendChunk([{part_body, Data}|Rest], State) -> sendChunk([{body, Data}|Rest], State); sendChunk([], State) when State#send.last/=true -> {cont, State}; sendChunk([], S0) when S0#send.last==true, S0#send.boundary/=[] -> if S0#send.estate /= "" -> smtp_send_b64_final(S0); true -> ok end, S = S0#send{estate=""}, smtp_send_part(S, ["\r\n--",S#send.boundary,"--\r\n"]), smtp_close(S), {done, {redirect_local, {rel_path, "mail.yaws"}}}; sendChunk([], State) when State#send.last==true, State#send.boundary==[] -> smtp_send_part(State, ["\r\n.\r\n"]), {done, {redirect_local, {rel_path, "mail.yaws"}}}; sendChunk([{head, {"to", _Opts}}|Rest], State) -> sendChunk(Rest, State#send{param=to}); sendChunk([{head, {"cc", _Opts}}|Rest], State) -> sendChunk(Rest, State#send{param=cc}); sendChunk([{head, {"bcc", _Opts}}|Rest], State) -> sendChunk(Rest, State#send{param=bcc}); sendChunk([{head, {"subject", _Opts}}|Rest], State) -> sendChunk(Rest, State#send{param=subject}); sendChunk([{head, {"html_subject", _Opts}}|Rest], State) -> sendChunk(Rest, State#send{param=ignore}); sendChunk([{head, {"message", _Opts}}|Rest], S) -> RTo = parse_addr(S#send.to), RCc = parse_addr(S#send.cc), RBcc = parse_addr(S#send.bcc), Recipients = RTo ++ RCc ++ RBcc, {ok, Port} = smtp_init(smtpserver(), S#send.session, Recipients), S2 = S#send{port=Port}, MailDomain = maildomain(), Session = S#send.session, CommonHeaders = [mail_header("To: ", S#send.to), mail_header("From: ", Session#session.user++"@"++MailDomain), mail_header("Cc: ", S#send.cc), mail_header("Bcc: ", S#send.bcc), mail_header("Subject: ", S#send.subject)], {Headers,S3} = case S#send.attached of "no" -> {CommonHeaders ++ [mail_header("Content-Type: ", "text/plain"), mail_header("Content-Transfer-Encoding: ", "8bit")], S2}; "yes" -> Boundary="--Next_Part("++boundary_date()++")--", {CommonHeaders ++ [mail_header("Mime-Version: ", "1.0"), mail_header("Content-Type: ", "Multipart/Mixed;\r\n boundary=\""++ Boundary++"\""), mail_header("Content-Transfer-Encoding: ", "8bit")], S2#send{boundary=Boundary}} end, smtp_send_part(S3, [Headers,"\r\n"]), case S3#send.attached of "yes" -> smtp_send_part(S3, ["--",S3#send.boundary,"\r\n", mail_header("Content-Type: ", "Text/Plain; charset=us-ascii"), mail_header("Content-Transfer-Encoding: ", "8bit"), "\r\n"]); "no" -> ok end, sendChunk(Rest, S3#send{param=message}); sendChunk([{head, {"attached", _Opts}}|Rest], State) -> sendChunk(Rest, State#send{param=attached}); sendChunk([{head, {_File, _Opts}}|Rest], S) when S#send.attached=="no" -> sendChunk(Rest, S#send{param=ignore}); sendChunk([{head, {_File, Opts}}|Rest], S0) when S0#send.attached=="yes" -> % io:format("attachment head\n"), if S0#send.estate /= "" -> smtp_send_b64_final(S0); true -> ok end, S = S0#send{estate=""}, FilePath = getopt(filename, Opts), case FilePath of [_|_] -> FileName = basename(FilePath), ContentType = content_type(FileName), smtp_send_part(S, ["\r\n--",S#send.boundary,"\r\n", mail_header("Content-Type: ", ContentType), mail_header("Content-Transfer-Encoding: ", "base64"), mail_header("Content-Disposition: ", "attachment; filename=\""++ FileName++"\""), "\r\n" ]), sendChunk(Rest, S#send{param=file}); _ -> sendChunk(Rest, S#send{param=ignore}) end; sendChunk([{body, Data}|Rest], S) -> case S#send.param of to -> sendChunk(Rest, S#send{to=S#send.to++Data}); cc -> sendChunk(Rest, S#send{cc=S#send.cc++Data}); bcc -> sendChunk(Rest, S#send{bcc=S#send.bcc++Data}); subject -> sendChunk(Rest, S#send{subject=S#send.subject++Data}); attached -> sendChunk(Rest, S#send{attached=S#send.attached++Data}); message -> NewS = smtp_send_part_message(S, Data), sendChunk(Rest, NewS); ignore -> sendChunk(Rest, S); file -> %io:format("sending body chunk\n"), NewS = smtp_send_b64(S, Data), sendChunk(Rest, NewS) end. send(Session, To, Cc, Bcc, Subject, Msg) -> tick_session(Session#session.cookie), RTo = parse_addr(To), RCc = parse_addr(Cc), RBcc = parse_addr(Bcc), Recipients = RTo ++ RCc ++ RBcc, Date = date_and_time_to_string(yaws:date_and_time()), MailDomain = maildomain(), Headers = [mail_header("To: ", To), mail_header("From: ", Session#session.user++"@"++MailDomain), mail_header("Cc: ", Cc), mail_header("Bcc: ", Bcc), mail_header("Subject: ", Subject), mail_header("Content-Type: ", "text/plain"), mail_header("Content-Transfer-Encoding: ", "8bit")], Message = io_lib:format("~sDate: ~s\r\n\r\n~s\r\n.\r\n", [Headers, Date, Msg]), case smtp_send(smtpserver(), Session, Recipients, Message) of ok -> {redirect_local, {rel_path,"mail.yaws"}}; {error, Reason} -> (dynamic_headers() ++ compose(Session, Reason, To, Cc, Bcc, Subject, Msg)) end. mail_header(_Key, []) -> []; mail_header(Key, Val) -> Key++Val++"\r\n". compose(Session) -> compose(Session, "","","","","",""). compose(Session, Reason, To, Cc, Bcc, Subject, Msg) -> tick_session(Session#session.cookie), (dynamic_headers()++ [{ehtml, [{script,[{src,"mail.js"}],[]}, {style, [{type,"text/css"}], "A:link { color: 0;text-decoration: none}\n" "A:visited { color: 0;text-decoration: none}\n" "A:active { color: 0;text-decoration: none}\n" "textarea { background-color: #fff; border: 1px solid 00f; }\n" "DIV.tag-body { background: white; }\n"}, % {script, [{type,"text/javascript"}], % "_editor_url='/htmlarea/';\n" % "_editor_lagn='se';\n"}, % {script, [{type,"text/javascript"},{src,"/htmlarea/htmlarea.js"}],""}, % {script, [{type,"text/javascript"}], % "var editor = null;\n" % "function initEditor() {\n" % "editor = new HTMLArea('html_message');\n" % "editor.generate();\n" % "return false;\n}"}, % {script,[{type,"text/javascript"},{defer,"1"}], %% "HTMLArea.replace('html_message');\n"}, % "HTMLArea.replaceAll();\n"}, {body,[{bgcolor,silver},{marginheight,0},{link,"#000000"}, {topmargin,0},{leftmargin,0},{rightmargin,0}, {marginwidth,0}, % {onload, "initEditor();document.compose.to.focus();"}], {onload, "document.compose.to.focus();"}], [{form, [{name,compose},{action,"send.yaws"},{method,post}, {enctype,"multipart/form-data"} ], [{table, [{border,0},{bgcolor,"c0c0c0"},{cellspacing,0}, {width,"100%"}], {tr,[],{td,[{nowrap,true},{align,left},{valign,middle}], {font, [{size,6},{color,black}], "Yaws WebMail at "++maildomain()}}}}, build_toolbar([{"tool-send.gif", "javascript:setComposeCmd('send');","Send"}, {"", "mail.yaws", "Close"}]), {input,[{type,hidden},{name,attached},{value,"no"}],[]}, {table, [{width,645},{border,0},{bgcolor,silver},{cellspacing,0}, {cellpadding,0}], if Reason == [] -> []; true -> [ {tr,[],[{td,[{colspan,2},{height,35},{align,left}, {valign,top}], {font,[{color,red},{size,2},nowrap], ["Error: ",Reason]}}]} ] end ++ [{tr,[],[{td,[{height,0},{align,left},{valign,top}],[]}, {td,[{height,0},{align,left},{valign,top}],[]}]}, {tr,[],[{td,[{height,35},{align,left},{valign,top}], {font,[{color,"#000000"},{size,2},nowrap], "&nbsp;To:&nbsp;"}}, {td,[{height,35},{align,left},{valign,top}], {input,[{name,to},{type,text},{size,66}, {check,value,quote(To)}]}}]}, {tr,[],[{td,[{height,0},{align,left},{valign,top}],[]}, {td,[{height,0},{align,left},{valign,top}],[]}]}, {tr,[],[{td,[{height,35},{align,left},{valign,top}], {font,[{color,"#000000"},{size,2},nowrap], "&nbsp;Cc:&nbsp;"}}, {td,[{height,35},{align,left},{valign,top}], {input,[{name,cc},{type,text},{size,66}, {check,value,quote(Cc)}]}}]}, {tr,[],[{td,[{height,0},{align,left},{valign,top}],[]}, {td,[{height,0},{align,left},{valign,top}],[]}]}, {tr,[],[{td,[{height,35},{align,left},{valign,top}], {font,[{color,"#000000"},{size,2},nowrap], "&nbsp;Bcc:&nbsp;"}}, {td,[{height,35},{align,left},{valign,top}], {input,[{name,bcc},{type,text},{size,66}, {check,value,quote(Bcc)}]}} ]}, {tr,[],[{td,[{height,35},{align,left},{valign,top},nowrap], {font,[{color,"#000000"},{size,2}], "&nbsp;Subject:&nbsp;"}}, {td,[{colspan,3},{align,left},{valign,top}], {input,[{name,subject},{type,text},{size,66}, {check,value,quote(Subject)}]}}]} ] }, {input,[{type,hidden},{name,message},{value,""}],[]}, {table,[{width,645},{border,0},{cellspacing,0},{cellpadding,0}], {tr,[], [ build_tabs(["Message","Attachments"]), {'div', [{id, "tab-body:0"},{style,"display: block;"}], {table, [{bgcolor,silver},{border,0},{cellspacing,0}, {cellpadding,0}], {tr,[], {td,[{align,left},{valign,top}], [{textarea, [{wrap,virtual}, {name,html_message}, {id,html_message}, {cols,80},{rows,24}], Msg}, % {a, [{href,"javascript:alert(editor.getHTML());"}],"html"}, % " ", % {a, [{href,"javascript:document.compose.foo.innerHTML=editor.getHTML();alert(document.compose.foo.value);"}],"debug"}, % " ", % {a, [{href,"javascript:filur();"}],"debug"}, "" ] } } } }, {'div', [{id, "tab-body:1"},{style,"display: none;"}], {table, [{bgcolor,silver},{border,0},{cellspacing,0}, {cellpadding,0}], {tr,[], {td,[{align,left},{valign,top}], ["Attached files:", {table,[], file_attachements(10) } ] } } } } ] } }, % {textarea, [{wrap,virtual}, % {name,foo}, % {id,foo}, % {cols,80},{rows,24}], % ""}, {input,[{type,hidden},{name,cmd},{value,""}],[]} ] } ] } ] }]). file_attachements(0) -> []; file_attachements(N) -> [file_attachement(N)|file_attachements(N-1)]. file_attachement(N) -> I = integer_to_list(N), {tr,[], [{td,[],"File: "}, {td,[], {input, [{type,"file"},{name,"file"++I},{size,"30"}],[]}} ] }. build_tabs(Tabs) -> [{script,[{type,"text/javascript"}], ["tabCount = ",integer_to_list(length(Tabs)),";\n"]}, {'div', [{align,"left"}], {table,[{border,"0"}, {cellspacing,"0"}, {cellpadding,"0"}], {tr,[], build_tab(Tabs,0)}}}, {'div',[{align,"left"}], {table,[{width,645},{border,0},{cellspacing,0},{cellpadding,0}], {tr,[],{td,[{height,8},{background,"tab-hr.gif"}],[]}}}} ]. build_tab([],_) -> []; build_tab([T|Ts], N=0) -> I = integer_to_list(N), [{td,[{width,6}], {img,[{src,"tab-left_active.gif"}, {border,0}, {id,"tab-left:"++I}],[]}}, {td,[{align,"center"}, {style,"cursor: pointer; background: url(tab-bg_active.gif)"}, {onClick,"changeActiveTab("++I++")"}, {id,"tab-bg:"++I}], T}, {td, [{width,6}], {img,[{src,"tab-right_active.gif"}, {border,0}, {id,"tab-right:"++I}],[]}}| build_tab(Ts,N+1)]; build_tab([T|Ts], N) -> I = integer_to_list(N), [{td,[{width,6}], {img,[{src,"tab-left_inactive.gif"}, {border,0}, {id,"tab-left:"++I}],[]}}, {td,[{align,"center"}, {style,"cursor: pointer; background: url(tab-bg_inactive.gif)"}, {onClick,"changeActiveTab("++I++")"}, {id,"tab-bg:"++I}], T}, {td, [{width,6}], {img,[{src,"tab-right_inactive.gif"}, {border,0}, {id,"tab-right:"++I}],[]}}| build_tab(Ts,N+1)]. showmail(Session, MailNr) -> showmail(Session, MailNr, ?RETRYCOUNT). showmail(_Session, _MailNr, 0) -> {ehtml,format_error("Mailbox locked by other mail session.")} ; showmail(Session, MailNr, Count) -> tick_session(Session#session.cookie), Formated = case retr(popserver(), Session#session.user, Session#session.passwd, MailNr) of {error, Reason} -> case string:str(lowercase(Reason), "lock") of 0 -> format_error(to_string(Reason)); _N -> sleep(?RETRYTIMEOUT), showmail(Session, MailNr, Count-1) end; Message -> format_message(Session, Message, MailNr, "1") end, (dynamic_headers() ++ [{ehtml, [{script,[{src,"mail.js"}], []}, {style, [{type,"text/css"}], ".conts { visibility:hidden }\n" "A:link { color: 0;text-decoration: none}\n" "A:visited { color: 0;text-decoration: none}\n" "A:active { color: 0;text-decoration: none}\n" "DIV.msg-body { background: white; }\n" }, {body,[{bgcolor,silver},{marginheight,0},{topmargin,0},{leftmargin,0}, {rightmargin,0},{marginwidth,0}], [{table, [{border,0},{bgcolor,"c0c0c0"},{cellspacing,0}, {width,"100%"}], {tr,[],{td,[{nowrap,true},{align,left},{valign,middle}], {font, [{size,6},{color,black}], "WebMail at "++maildomain()}}}}] ++ Formated } ]}]). list(Session, {Refresh,Sort}) -> list_msg(Session, Refresh, Sort, ?RETRYCOUNT). list_msg(_Session, _Refresh, _Sort, 0) -> {ehtml,format_error("Mailbox locked by other mail process.")}; list_msg(Session, Refresh, Sort, Count) -> tick_session(Session#session.cookie), OldList = Session#session.listing, Listing = if Refresh == true -> list(popserver(), Session#session.user, Session#session.passwd); OldList == undefined -> list(popserver(), Session#session.user, Session#session.passwd); true -> OldList end, Sorting = case Sort of undefined -> Session#session.sorting; _ -> set_sorting(Session#session.cookie, Sort), Sort end, case Listing of {error, Reason} -> case string:str(lowercase(Reason), "lock") of 0 -> {ehtml,format_error(to_string(Reason))}; _N -> sleep(?RETRYTIMEOUT), list_msg(Session, Refresh, Sort, Count-1) end; H when Refresh == true -> set_listing(Session#session.cookie, H), {redirect_local, {rel_path, "mail.yaws"}}; H -> if H /= OldList -> set_listing(Session#session.cookie, H); true -> ok end, (dynamic_headers()++ [{ehtml, [{script,[], "function setCmd(val) { \n" " if (val == 'delete') {\n" " var res = confirm('Are you sure you want" " to delete the selected emails?');\n" " if (!res) { \n" " return;\n" " }\n" " }\n" " document.list.cmd.value=val;\n" " document.list.submit();\n" "}" }, {style,[{type,"text/css"}], "A:link { color: black; text-decoration: none}\n" "A:visited { color: black; text-decoration: none}\n" "A:active { color: black; text-decoration: none}\n" ".AList { color: black; text-decoration: none}\n" ".Head { border-right:1px solid white}"}, {form, [{name,list},{action,"listop.yaws"},{method,post}], [{table, [{border,0},{bgcolor,"c0c0c0"}, {cellspacing,0},{width,"100%"}], {tr,[],{td,[{nowrap,true},{align,left},{valign,middle}], {font, [{size,6},{color,black}], "WebMail at "++maildomain()}}}}, build_toolbar([{"tool-newmail.gif","compose.yaws", "New Message"}, {"tool-delete.gif", "javascript:setCmd('delete')", "Delete"}, {"","mail.yaws?refresh=true","Refresh"}, {"","logout.yaws","Logout"}]), {table, [{border,0},{bgcolor,"666666"},{cellspacing,0}, {width,"100%"}], {tr,[],{td,[{nowrap,true},{align,left},{valign,middle}], {font, [{size,2},{color,"#ffffff"}], "Inbox for "++Session#session.user}}}}, {table, [{border,0},{cellspacing,0},{cellpadding,1}, {width,"100%"}], [{tr, [{bgcolor,"c0c0c0"},{valign,middle}], [{th,[{align,left},{valign,middle},{class,head}], {font,[{size,2},{color,black}], sort_href("nr",Sorting,"Nr")}}, {th,[{class,head}], {img,[{src,"view-mark.gif"},{width,13}, {height,13}],[]}}, {th,[{align,left},{valign,middle},{class,head}], {font,[{size,2},{color,black}], sort_href("from",Sorting,"From")}}, {th,[{align,left},{valign,middle},{class,head}], {font,[{size,2},{color,black}], sort_href("subject",Sorting,"Subject")}}, {th,[{align,left},{valign,middle},{class,head}], {font,[{size,2},{color,black}], sort_href("date",Sorting,"Date")}}, {th,[{align,left},{valign,middle},{class,head}], {font,[{size,2},{color,black}], sort_href("size",Sorting,"Size")}}]}] ++ format_summary(H,Sorting)}, {input,[{type,hidden},{name,cmd},{value,""}],[]} ]}]}]) end. sort_href(Sort, Cur, Text) when is_atom(Cur) -> sort_href(Sort, atom_to_list(Cur), Text); sort_href(Sort, Sort, Text) -> [{a, [{href,"mail.yaws?sort=rev_"++Sort}], Text}, {img, [{src,"up.gif"}]}]; sort_href(Sort, "rev_"++Sort, Text) -> [{a, [{href,"mail.yaws?sort="++Sort}], Text}, {img, [{src,"down.gif"}]}]; sort_href(Sort, _Cur, Text) -> {a, [{href,"mail.yaws?sort="++Sort}], Text}. format_summary(Hs,Sorting) -> SHs = sort_summary(Hs, Sorting), [format_summary_line(H) || H <- SHs]. sort_summary(Hs, Sorting) -> lists:sort(fun(A,B) -> summary_compare(A,B,Sorting) end, Hs). summary_compare(A, B, rev_from) -> not(summary_compare(A, B, from)); summary_compare(A, B, rev_date) -> not(summary_compare(A, B, date)); summary_compare(A, B, rev_subject) -> not(summary_compare(A, B, subject)); summary_compare(A, B, rev_nr) -> not(summary_compare(A, B, nr)); summary_compare(A, B, rev_size) -> not(summary_compare(A, B, size)); summary_compare(A,B,size) -> Sa = A#info.size, Sb = B#info.size, if Sa < Sb -> true; Sa > Sb -> false; true -> summary_compare(A,B,date) end; summary_compare(A,B,from) -> Ha = A#info.headers, Hb = B#info.headers, if Ha#mail.from_fmt_lc < Hb#mail.from_fmt_lc -> true; Ha#mail.from_fmt_lc == Hb#mail.from_fmt_lc -> summary_compare(A,B,date); true -> false end; summary_compare(A,B,subject) -> Ha = A#info.headers, Hb = B#info.headers, Sa = Ha#mail.subject_fmt_lc, Sb = Hb#mail.subject_fmt_lc, if Sa < Sb -> true; Sa > Sb -> false; true -> summary_compare(A,B,date) end; summary_compare(A,B,date) -> Ha = A#info.headers, Hb = B#info.headers, Ha#mail.date_pst < Hb#mail.date_pst; summary_compare(A,B,_Nr) -> A#info.nr < B#info.nr. strip_re(" "++Subject) -> strip_re(Subject); strip_re("re:"++Subject) -> strip_re(Subject); strip_re("aw:"++Subject) -> strip_re(Subject); strip_re("ang."++Subject) -> strip_re(Subject); strip_re(Subject) -> Subject. format_summary_line(I) -> H = I#info.headers, {tr, [{align,center},{valign,top}], [{td, [{nowrap,true},{align,left},{valign,top},{class,"List"}], {a, [{href,"showmail.yaws?nr="++integer_to_list(I#info.nr)}], {font,[{size,2},{color,black}],{b,[],integer_to_list(I#info.nr)}}}}, {td, [{nowrap,true},{align,center},{valign,top},{class,"List"}], {input, [{type,checkbox},{name,I#info.nr},{value,yes}],[]}}, {td, [{nowrap,true},{align,left},{valign,top},{class,"List"}], {a, [{href,"showmail.yaws?nr="++integer_to_list(I#info.nr)}], {font,[{size,2},{color,black}],{b,[],H#mail.from_fmt}}}}, {td, [{nowrap,true},{align,left},{valign,top},{class,"List"}], {a, [{href,"showmail.yaws?nr="++integer_to_list(I#info.nr)}], {font,[{size,2},{color,black}],{b,[],H#mail.subject_fmt}}}}, {td, [{nowrap,true},{align,left},{valign,top},{class,"List"}], {a, [{href,"showmail.yaws?nr="++integer_to_list(I#info.nr)}], {font,[{size,2},{color,black}], {b,[],H#mail.date_fmt}}}}, {td, [{nowrap,true},{align,left},{valign,top},{class,"List"}], {a, [{href,"showmail.yaws?nr="++integer_to_list(I#info.nr)}], {font,[{size,2},{color,black}],{b,[],integer_to_list(I#info.size)}}}} ]}. format_from(From0) -> From = lists:flatten(From0), case string:chr(From,$<) of 0 -> string:strip(From); N -> NewF=string:strip(unquote(decode(string:substr(From,1,N-1)))), if NewF == [] -> From; true -> NewF end end. parse_addr(AddrStr) -> Addrs = token_addrs(AddrStr, [], false), Op = fun(From) -> case {string:chr(From,$<),string:chr(From,$>)} of {S,E} when S>0, E>0 -> string:substr(From,S,(E-S)+1); _ -> string:strip(From) end end, [Op(F) || F <- Addrs]. token_addrs([], [], _) -> []; token_addrs([], Acc, _) -> [lists:reverse(Acc)]; token_addrs([C=$"|R], Acc, true) -> token_addrs(R, [C|Acc], false); token_addrs([C=$"|R], Acc, false) -> token_addrs(R, [C|Acc], true); token_addrs([$,|R], Acc, false) -> [lists:reverse(Acc)|token_addrs(R, [], false)]; token_addrs([C|R], Acc, InQuote) -> token_addrs(R, [C|Acc], InQuote). decode(Text) -> decode(Text, []). decode([], Acc) -> lists:reverse(Acc); decode([$=,$?|Rest], Acc) -> decode_scan(Rest, Acc); decode([C|Cs], Acc) -> decode(Cs, [C|Acc]). decode_scan([], Acc) -> lists:reverse(Acc); decode_scan([$?,$b,$?|Rest], Acc) -> decode_b64(Rest,Acc); decode_scan([$?,$B,$?|Rest], Acc) -> decode_b64(Rest,Acc); decode_scan([$?,$q,$?|Rest], Acc) -> decode_q(Rest,Acc); decode_scan([$?,$Q,$?|Rest], Acc) -> decode_q(Rest, Acc); decode_scan([$?,_,$?|Rest], Acc) -> decode(Rest, Acc); decode_scan([_|Rest], Acc) -> decode_scan(Rest, Acc). decode_q([], Acc) -> lists:reverse(Acc); decode_q([$?,$=|Rest], Acc) -> decode(Rest, Acc); decode_q([$=,H1,H2|Rest], Acc) -> case catch yaws:hex_to_integer([H1,H2]) of {'EXIT',_} -> decode_q(Rest, [H2,H1,$=|Acc]); C -> decode_q(Rest, [C|Acc]) end; decode_q([C|Cs], Acc) -> decode_q(Cs, [C|Acc]). decode_b64([],Acc) -> Str = lists:reverse(Acc), case catch base64_2_str(Str) of {'EXIT',_} -> Str; Dec -> Dec end; decode_b64([$?,$=|Rest],Acc) -> Str = lists:reverse(Acc), case catch base64_2_str(Str) of {'EXIT',_} -> Str++decode(Rest); Dec -> Dec ++ decode(Rest) end; decode_b64([C|Rest], Acc) -> decode_b64(Rest,[C|Acc]). unquote([]) -> []; unquote([$"|R]) -> unquote(R); unquote([C|R]) -> [C|unquote(R)]. quote([]) -> []; quote([$"|Cs]) -> ["&quot;"|quote(Cs)]; quote([C|Cs]) -> [C|quote(Cs)]. display_login(_A, Status) -> (dynamic_headers() ++ [{ehtml, [{body, [{onload,"document.f.user.focus();"}], [{table, [{border,0},{bgcolor,"c0c0c0"},{cellspacing,0}, {width,"100%"}], {tr,[],{td,[{nowrap,true},{align,left},{valign,middle}], {font, [{size,6},{color,black}], "WebMail at "++maildomain()}}}}, io_lib:format("<p>Your login status is: ~s</p>", [Status]), {form, [{method,post}, {name,f}, {action, "login.yaws"}, {autocomplete,"off"}], {table,[{cellspacing, "5"}], [{tr, [], [{td, [], {p, [], "Username:"}}, {td, [], {input, [{name, user}, {type, text}, {size, "20"}]}} ]}, {tr, [], [{td, [], {p, [], "Password:"}}, {td, [], {input, [{name, password}, {type, password}, {size, "20"}]}}]}, {tr, [], {td, [{align, "right"}, {colspan, "2"}], {input, [{type, submit}, {value, "Login"}]}}} ]}}] }] }]). logout(Session) -> logout_cookie(Session#session.cookie), (dynamic_headers() ++ [{redirect_local, {rel_path,"mail.yaws"}}]). login(User, Password) -> case stat(popserver(), strip(User), strip(Password)) of {ok, _} -> {ok, new_session(User, Password)}; {error, Reason} -> {error, Reason} end. check_session(A) -> H = A#arg.headers, case yaws_api:find_cookie_val("mailsession", H#headers.cookie) of [] -> display_login(A, "not logged in"); CVal -> case mail:check_cookie(CVal) of error -> display_login(A, "not logged in"); Session -> {ok, Session} end end. strip(Str) -> lists:filter(fun(C)->not(lists:member(C,"\r\n"))end,Str). dynamic_headers() -> [yaws_api:set_content_type("text/html"), {header, {cache_control, "no-store"}}, {header, "Expires: -1"}]. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% session server %% tick_session(Cookie) -> session_server(), mail_session_manager ! {tick_session, Cookie}. new_session(User, Password) -> session_server(), mail_session_manager ! {new_session, #session{user=User,passwd=Password}, self()}, receive {session_manager, Cookie} -> Cookie end. check_cookie(Cookie) -> session_server(), mail_session_manager ! {get_session, Cookie, self()}, receive {session_manager, {ok, Session}} -> Session; {session_manager, error} -> error end. set_listing(Cookie, Listing) -> session_server(), mail_session_manager ! {set_listing, Cookie, self(), Listing}, receive {session_manager, listing_added} -> ok; {session_manager, error} -> error end. set_sorting(Cookie, Sorting) -> session_server(), mail_session_manager ! {set_sorting, Cookie, self(), Sorting}, receive {session_manager, sorting_added} -> ok; {session_manager, error} -> error end. logout_cookie(Cookie) -> session_server(), mail_session_manager ! {del_session, Cookie}. session_server() -> case whereis(mail_session_manager) of undefined -> Pid = proc_lib:spawn(?MODULE, session_manager_init, []), register(mail_session_manager, Pid); _ -> done end. session_manager_init() -> session_manager([], now(), read_config()). session_manager(C0, LastGC0, Cfg) -> %% Check GC first to avoid GC starvation. GCDiff = diff(LastGC0,now()), {LastGC, C} = if GCDiff > 5000 -> C2 = session_manager_gc(C0, Cfg), {now(), C2}; true -> {LastGC0, C0} end, receive {get_session, Cookie, From} -> case lists:keysearch(Cookie, 1, C) of {value, {_,Session,_}} -> From ! {session_manager, {ok, Session}}; false -> From ! {session_manager, error} end, session_manager(C, LastGC, Cfg); {new_session, Session, From} -> Cookie = integer_to_list(bin2int(crypto:rand_bytes(16))), From ! {session_manager, Cookie}, session_manager([{Cookie, Session#session{cookie=Cookie}, now()}|C], LastGC, Cfg); {tick_session, Cookie} -> case lists:keysearch(Cookie, 1, C) of {value, {Cookie,Session,_}} -> session_manager( lists:keyreplace(Cookie,1,C, {Cookie,Session,now()}), LastGC, Cfg); false -> session_manager(C, LastGC, Cfg) end; {del_session, Cookie} -> C3 = lists:keydelete(Cookie, 1, C), session_manager(C3, LastGC, Cfg); {From, cfg , Req} -> sm_reply(Req, From, Cfg), session_manager(C, LastGC, Cfg); {set_listing, Cookie, From, Listing} -> case lists:keysearch(Cookie, 1, C) of {value, {_,Session,_}} -> S2 = Session#session{listing=Listing}, From ! {session_manager, listing_added}, session_manager(lists:keyreplace( Cookie, 1, C, {Cookie, S2, now()}), LastGC, Cfg); false -> io:format("Error, no session found! ~p\n", [Cookie]), From ! {session_manager, error}, session_manager(C, LastGC, Cfg) end; {set_sorting, Cookie, From, Sorting} -> case lists:keysearch(Cookie, 1, C) of {value, {_,Session,_}} -> S2 = Session#session{sorting=Sorting}, From ! {session_manager, sorting_added}, session_manager(lists:keyreplace( Cookie, 1, C, {Cookie, S2, now()}), LastGC, Cfg); false -> io:format("Error, no session found! ~p\n", [Cookie]), From ! {session_manager, error}, session_manager(C, LastGC, Cfg) end; {session_set_attach_data, From, Cookie, Fname, Ctype, Data} -> case lists:keysearch(Cookie, 1, C) of {value, {_,Session,_}} -> Atts = Session#session.attachments, [A|As] = add_att(Fname, Ctype, Data, Atts), From ! {session_manager, A#satt.num}, S2 = Session#session{attachments = [A|As]}, session_manager(lists:keyreplace( Cookie,1,C, {Cookie,S2,now()}), LastGC, Cfg); false -> session_manager(C, LastGC, Cfg) end; {session_get_attach_data, From, Cookie, Num} -> case lists:keysearch(Cookie, 1, C) of {value, {_,Session,_}} -> Atts = Session#session.attachments, case lists:keysearch(Num, #satt.num, Atts) of false -> From ! {session_manager, error}; {value, A} -> From ! {session_manager, A} end; false -> ignore end, session_manager(C, LastGC, Cfg) after 5000 -> %% garbage collect sessions C3 = session_manager_gc(C, Cfg), session_manager(C3, now(), Cfg) end. add_att(Fname, Ctype, Data, Atts) -> case lists:keysearch(Fname, #satt.filename, Atts) of false -> [#satt{num = length(Atts) + 1, filename = Fname, ctype = Ctype, data = Data} | Atts]; {value, A} when A#satt.data == Data -> [A | lists:keydelete(A#satt.num, #satt.num, Atts)]; {value, _A} -> [#satt{num = length(Atts) + 1, filename = Fname, ctype = Ctype, data = Data} | Atts] end. session_manager_gc(C, Cfg) -> lists:zf(fun(Entry={_Cookie,_Session,Time}) -> Diff = diff(Time,now()), TTL = Cfg#cfg.ttl, if Diff > TTL -> false; true -> {true, Entry} end end, C). sm_reply(ttl, From, Cfg) -> From ! {session_manager, Cfg#cfg.ttl}; sm_reply(popserver, From, Cfg) -> From ! {session_manager, Cfg#cfg.popserver}; sm_reply(smtpserver, From, Cfg) -> From ! {session_manager, Cfg#cfg.smtpserver}; sm_reply(maildomain, From, Cfg) -> From ! {session_manager, Cfg#cfg.maildomain}; sm_reply(sendtimeout, From, Cfg) -> From ! {session_manager, Cfg#cfg.sendtimeout}. req(Req) -> session_server(), mail_session_manager ! {self(), cfg, Req}, receive {session_manager, Reply} -> Reply after 10000 -> exit("No reply from session manager") end. % ttl() -> req(ttl). popserver() -> req(popserver). smtpserver() -> req(smtpserver). maildomain() -> req(maildomain). sendtimeout() -> req(sendtimeout). diff({M1,S1,_}, {M2,S2,_}) -> (M2-M1)*1000000+(S2-S1). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% retr(Server, User, Password, Nr) -> Req = [ret(Nr)], case pop_request(Req, Server, User, Password) of [{ok,Msg}] -> dot_unescape(Msg); [{error, Reason}] -> {error, Reason} end. parse_message(Msg) -> split_head_body(Msg, []). split_head_body(Msg, Acc) -> case get_next_line(Msg) of {error, Reason} -> {error, Reason}; {[], Rest} -> {lists:reverse(Acc), Rest}; {Line, Rest} -> split_head_body(Rest, [Line|Acc]) end. get_next_line(Data) -> %% io:format("Data = ~p\n", [Data]), get_next_line(Data,[]). get_next_line([D|Ds], Acc) -> case split_reply(D,[]) of more -> get_next_line(Ds, [D|Acc]); {Pre, Rest} when Acc==[] -> {Pre, [Rest|Ds]}; {Pre, Rest} -> {lists:flatten(lists:reverse([Pre|Acc])), [Rest|Ds]} end. stat(Server, User, Password) -> case pop_request([{"STAT",sl}], Server, User, Password) of [{ok, Stat}] -> {ok, Stat}; {error, Reason} -> {error, Reason} end. list(Server, User, Password) -> case pop_request([{"LIST",ml}], Server, User, Password) of [{ok, Stats}] -> Info = lists:reverse([info(S) || S <- Stats]), Req = [top(I#info.nr) || I <- Info], case pop_request(Req, Server, User, Password) of {error, Reason} -> {error, Reason}; Res -> Hdrs = lists:map(fun({ok,Ls}) -> parse_headers(Ls) end, Res), add_hdrs(Info,Hdrs) end; {error, Reason} -> {error, Reason} end. add_hdrs([], []) -> []; add_hdrs([I|Is], [H|Hs]) -> [I#info{headers=H}|add_hdrs(Is,Hs)]. info(Str) -> [NrStr,SizeStr|_] = string:tokens(Str, " \t"), #info{nr=to_int(NrStr),size=to_int(SizeStr)}. top(I) -> {"TOP "++integer_to_list(I)++" 0", ml}. ret(I) -> {"RETR "++integer_to_list(I), sized}. del(I) -> {"DELE "++I, sl}. to_int(Str) -> to_int(Str, 0). to_int([D|Ds], Acc) when D >= $0, D =< $9-> to_int(Ds, Acc*10+D-$0); to_int(_, Acc) -> Acc. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% parse_headers(Lines) -> parse_headers(Lines, #mail{}). parse_headers([], Headers) -> Headers; parse_headers([L1,[$\t|L2]|Lines], Headers) -> parse_headers([L1++" "++L2|Lines], Headers); parse_headers([L1,[$ |L2]|Lines], Headers) -> parse_headers([L1++" "++L2|Lines], Headers); parse_headers([Line|Lines], Headers) -> case string:chr(Line, $:) of 0 -> Headers; N -> Key = lowercase(string:strip(string:sub_string(Line, 1, N-1))), Value = if length(Line) > N+1 -> string:strip(string:sub_string(Line, N+2)); true -> [] end, NewH = add_header(Key, Value, Headers), parse_headers(Lines, NewH) end. parse_header_value(Header) -> [Key|Options] = string:tokens(Header, ";"), Opts = [parse_key_value(O) || O <- Options], {Key,Opts}. parse_key_value(O) -> parse_key_value(O, []). parse_key_value([], Acc) -> {string:strip(lists:reverse(Acc)), []}; parse_key_value([$=|Rest], Acc) -> Value = unquote(string:strip(Rest)), Key = lowercase(string:strip(lists:reverse(Acc))), {Key, Value}; parse_key_value([C|Cs], Acc) -> parse_key_value(Cs, [C|Acc]). lowercase(Str) -> [lowercase_ch(S) || S <- Str]. lowercase_ch(C) when C>=$A, C=<$Z -> C + 32; lowercase_ch(C) -> C. add_header("content-transfer-encoding", Value, H) -> H#mail{transfer_encoding = lowercase(Value)}; add_header("content-type", Value, H) -> H#mail{content_type = parse_header_value(Value)}; add_header("content-disposition", Value, H) -> H#mail{content_disposition = parse_header_value(Value)}; add_header("from", Value, H) -> FromFmt = format_from(Value), H#mail{from = Value, from_fmt = FromFmt, from_fmt_lc = lowercase(FromFmt)}; add_header("to", Value, H) -> H#mail{to = Value}; add_header("cc", Value, H) -> H#mail{cc = Value}; add_header("bcc", Value, H) -> H#mail{bcc = Value}; add_header("subject", Value, H) -> SubjectFmt = lists:flatten(decode(Value)), H#mail{subject = Value, subject_fmt = SubjectFmt, subject_fmt_lc = strip_re(lowercase(SubjectFmt))}; add_header("date", Value, H) -> DatePst = parse_date(Value), H#mail{date = Value, date_pst = DatePst, date_fmt = format_date(DatePst)}; add_header(Other, Value, H) -> H#mail{other = [{Other,Value}| H#mail.other]}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% pop_request(Command, Server, User, Password) -> proc_lib:spawn_link(?MODULE, ploop, [Command, Server, User, Password, self()]), receive {pop_response, Response} -> Response end. %% %% first authenticate then run a bunch of commands %% ploop(Command, Server, User, Password, From) -> case gen_tcp:connect(Server, 110, [{active, false}, {reuseaddr,true}, binary]) of {ok, Port} -> State = #pstate{port=Port, user=User, pass=Password, cmd=Command, from=From}, ploop(init, State); _ -> {error, "Failed to contact mail server."} end. % ploop(init, State) -> case receive_reply(State) of {ok, _Reply, State2} -> psend("USER " ++ State#pstate.user, State#pstate.port), ploop(user, State2); {error, Reason, _State2} -> State#pstate.from ! {pop_response, {error, Reason}}, pop_close(State#pstate.port); {more, State2} -> ploop(init, State2) end; ploop(user, State) -> case receive_reply(State) of {ok, _Reply, State2} -> psend("PASS " ++ State#pstate.pass, State#pstate.port), ploop(pass, State2); {error, Reason, _State2} -> State#pstate.from ! {pop_response, {error, Reason}}, pop_close(State#pstate.port); {more, State2} -> ploop(user, State2) end; ploop(pass, State) -> case receive_reply(State) of {ok, _Reply, _State2} -> next_cmd(State); {error, Reason, _State2} -> State#pstate.from ! {pop_response, {error, Reason}}, pop_close(State#pstate.port); {more, State2} -> ploop(pass, State2) end; ploop(sl, State) -> case receive_reply(State) of {ok, Reply, State2} -> next_cmd(State2#pstate{reply=[{ok,Reply}|State2#pstate.reply]}); {error, Reason, State2} -> next_cmd(State2#pstate{reply=[{error,Reason}| State2#pstate.reply]}); {more, State2} -> ploop(sl, State2) end; ploop(close, State) -> case receive_reply(State) of {ok, _Reply, State2} -> ploop(close, State2); {error, _, State2} -> next_cmd(State2); {more, State2} -> ploop(close, State2) end; ploop(sized, State) -> case receive_reply(State) of {ok, Reply, State2} -> case to_int(Reply) of 0 -> ploop(sized_cont, State2#pstate{remain=dot,dotstate=0, lines=[]}); Size -> ploop(sized_cont, State2#pstate{remain=Size,lines=[]}) end; {error, Reason, State2} -> next_cmd(State2#pstate{reply=[{error,Reason}| State2#pstate.reply]}); {more, State2} -> ploop(ml, State2) end; ploop(sized_cont, State) -> case receive_data(State) of {error, Reason, State2} -> next_cmd(State2#pstate{reply=[{error,Reason}| State2#pstate.reply]}); {more, State2} -> ploop(sized_cont, State2); {done, State2} -> Data = lists:reverse(State2#pstate.lines), next_cmd(State2#pstate{reply=[{ok, Data}|State2#pstate.reply]}) end; ploop(ml, State) -> case receive_reply(State) of {ok, _Reply, State2} -> ploop(ml_cont, State2#pstate{lines=[]}); {error, Reason, State2} -> next_cmd(State2#pstate{reply=[{error,Reason}| State2#pstate.reply]}); {more, State2} -> ploop(ml, State2) end; ploop(ml_cont, State) -> case receive_reply(State) of {line, Line, State2} -> Lines = State2#pstate.lines, ploop(ml_cont, State2#pstate{lines=[Line|Lines]}); {error, Reason, State2} -> next_cmd(State2#pstate{reply=[{error,Reason}| State2#pstate.reply]}); {more, State2} -> ploop(ml_cont, State2); {done, State2} -> Lines = lists:reverse(State2#pstate.lines), next_cmd(State2#pstate{reply=[{ok, Lines}|State2#pstate.reply]}) end. %% next_cmd(State=#pstate{cmd=Cmd,reply=Reply}) when Cmd==quit -> State#pstate.from ! {pop_response, lists:reverse(Reply)}, gen_tcp:close(State#pstate.port); next_cmd(State=#pstate{cmd=Cmd}) when Cmd==[]-> psend("QUIT", State#pstate.port), ploop(close, State#pstate{cmd=quit}); next_cmd(State=#pstate{cmd=[Cmd|Cmds]}) -> {C,S} = Cmd, psend(C, State#pstate.port), ploop(S, State#pstate{cmd=Cmds}). %% pop_close(Port) -> psend("quit", Port), gen_tcp:close(Port). %% psend(Str, Port) -> gen_tcp:send(Port, Str++"\r\n"). %% receive_reply(State=#pstate{acc=Acc,more=false}) -> check_reply(Acc, State); receive_reply(State=#pstate{port=Port,acc=Acc,more=true}) -> Res = gen_tcp:recv(Port, 0), case Res of {ok, Bin} -> NAcc = Acc++binary_to_list(Bin), check_reply(NAcc, State); {error, closed} -> {error, "closed", State}; Err -> {error, Err, State} end. %% receive_data(State=#pstate{acc=Acc,more=false,remain=Remain}) -> if Remain == dot -> %% look for .\r\n case find_dot(Acc, State#pstate.dotstate) of {more, DotState} -> State2 = State#pstate{acc=[], dotstate=DotState, lines=[Acc|State#pstate.lines], more=true}, {more, State2}; {ok, DotState, Lines, NAcc} -> State2 = State#pstate{acc=NAcc, dotstate=DotState, lines=[Lines|State#pstate.lines], more=false}, {done, State2} end; Remain =< length(Acc) -> {Lines, NAcc} = split_at(Acc, Remain), State2 = State#pstate{acc=NAcc,lines=[Lines|State#pstate.lines], remain=0,more=false}, {done, State2}; true -> Rem = Remain - length(Acc), State2 = State#pstate{acc=[],lines=[Acc|State#pstate.lines], remain=Rem, more=true}, {more, State2} end; receive_data(State=#pstate{acc=Acc,more=true}) when length(Acc)>0 -> receive_data(State#pstate{more=false}); receive_data(State=#pstate{port=Port,acc=[],more=true,remain=Remain}) -> Res = gen_tcp:recv(Port, 0), case Res of {ok, Bin} -> Acc = binary_to_list(Bin), if Remain == dot -> case find_dot(Acc, State#pstate.dotstate) of {more, DotState} -> State2 = State#pstate{acc=[], dotstate=DotState, lines=[Acc|State#pstate.lines], more=true}, {more, State2}; {ok, DotState, Lines, NAcc} -> State2 = State#pstate{acc=NAcc, dotstate=DotState, lines=[Lines|State#pstate.lines], more=false}, {done, State2} end; Remain =< length(Acc) -> {Lines, NAcc} = split_at(Acc, Remain), State2 = State#pstate{acc=NAcc, lines=[Lines|State#pstate.lines], remain=0,more=false}, {done, State2}; true -> Rem = Remain - length(Acc), State2 = State#pstate{acc=[], lines=[Acc|State#pstate.lines], remain=Rem, more=true}, {more, State2} end; Err -> {error, Err, State} end. %% check_reply(Str, State) -> case split_reply(Str, []) of {"+OK" ++ Res, Rest} -> NewS = State#pstate{acc=Rest,more=false}, {ok, Res, NewS}; {"-ERR" ++ Res, Rest} -> NewS = State#pstate{acc=Rest,more=false}, {error, Res, NewS}; {".", Rest} -> NewS = State#pstate{acc=Rest,more=false}, {done, NewS}; {"."++Line, Rest} -> NewS = State#pstate{acc=Rest,more=false}, {line, Line, NewS}; {Line, Rest} -> NewS = State#pstate{acc=Rest,more=false}, {line, Line, NewS}; more -> {more, State#pstate{acc=Str, more=true}} end. %% split_reply("\r\n"++Rest, Pre) -> {lists:reverse(Pre), Rest}; split_reply([H|T], Pre) -> split_reply(T, [H|Pre]); split_reply("", _Pre) -> more. %% split_at(L,N) -> split_at(L,N,[]). split_at(L,0,Acc) -> {lists:reverse(Acc),L}; split_at([C|Cs], N, Acc) -> split_at(Cs, N-1, [C|Acc]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% get_val(Key, L, Default) -> case lists:keysearch(Key, 1, L) of {value, {_, undefined}} -> Default; {value, {_, Val}} -> Val; _ -> Default end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% smtp_init(Server, Session, Recipients) -> {ok, Port} = gen_tcp:connect(Server, 25, [{active, false}, {reuseaddr,true}, binary]), smtp_expect(220, Port, "SMTP server does not respond"), smtp_put("MAIL FROM: " ++ Session#session.user++"@"++maildomain(), Port), smtp_expect(250, Port, "Sender not accepted by mail server"), send_recipients(Recipients,Port), smtp_put("DATA", Port), smtp_expect(354, Port, "Message not accepted by mail server."), {ok, Port}. smtp_close(State) -> smtp_put(".", State#send.port), smtp_expect(250, State#send.port, "Message not accepted by mail server."), gen_tcp:close(State#send.port), ok. smtp_send_part(State, Data) -> gen_tcp:send(State#send.port, Data). smtp_send_part_message(State, Data) -> {LastNL, Escaped} = dot_escape(Data, State#send.line_start), gen_tcp:send(State#send.port, Escaped), State#send{line_start=LastNL}. %% Add an . at all lines starting with a dot. dot_escape(Data, NL) -> dot_escape(Data, NL, []). dot_escape([], NL, Acc) -> {NL, lists:reverse(Acc)}; dot_escape([$.|Rest], true, Acc) -> dot_escape(Rest, false, [$.,$.|Acc]); dot_escape([$\n|Rest], _, Acc) -> dot_escape(Rest, true, [$\n|Acc]); dot_escape([C|Rest], _, Acc) -> dot_escape(Rest, false, [C|Acc]). %% dot_unescape(Data) -> {_,Dt} = dot_unescape(Data, true, []), Dt. dot_unescape([], NL, Acc) -> {NL, lists:reverse(Acc)}; dot_unescape([$.|Rest], true, Acc) -> dot_unescape(Rest, false, Acc); dot_unescape([$\n|Rest], _, Acc) -> dot_unescape(Rest, true, [$\n|Acc]); dot_unescape([L|Rest], NL, Acc) when is_list(L) -> {NL2, L2} = dot_unescape(L, NL, []), dot_unescape(Rest, NL2, [L2|Acc]); dot_unescape([C|Rest], _, Acc) -> dot_unescape(Rest, false, [C|Acc]). %% smtp_send_b64(State, Data0) -> Data = State#send.estate++Data0, {Rest,B64} = str2b64(Data), gen_tcp:send(State#send.port, B64), State#send{estate=Rest}. smtp_send_b64_final(State) -> Data = State#send.estate, B64 = str2b64_final(Data), gen_tcp:send(State#send.port, B64). smtp_send(Server, Session, Recipients, Message) -> case catch smtp_send2(Server, Session, Recipients, Message) of ok -> ok; {error, Reason} -> {error, Reason}; _ -> {error, "Failed to send message."} end. smtp_send2(Server, Session, Recipients, Message) -> {ok, Port} = gen_tcp:connect(Server, 25, [{active, false}, {reuseaddr,true}, binary]), smtp_expect(220, Port, "SMTP server does not respond"), smtp_put("MAIL FROM: " ++ Session#session.user++"@"++maildomain(), Port), smtp_expect(250, Port, "Sender not accepted by mail server"), send_recipients(Recipients,Port), smtp_put("DATA", Port), smtp_expect(354, Port, "Message not accepted by mail server."), smtp_put(Message, Port), smtp_put(".", Port), smtp_expect(250, Port, "Message not accepted by mail server."), smtp_put("QUIT", Port), ok. send_recipients([], _Port) -> ok; send_recipients([R|Rs], Port) -> smtp_put("RCPT TO: " ++ R, Port), smtp_expect(250, Port, io_lib:format("Recipient ~s not accepted.",[R])), send_recipients(Rs, Port). smtp_put(Message, Port) -> gen_tcp:send(Port, [Message,"\r\n"]). smtp_expect(Code, Port, ErrorMsg) -> smtp_expect(Code, Port, [], ErrorMsg). smtp_expect(Code, Port, Acc, ErrorMsg) -> Res = gen_tcp:recv(Port, 0, sendtimeout()), case Res of {ok, Bin} -> NAcc = Acc++binary_to_list(Bin), case string:chr(NAcc, $\n) of 0 -> smtp_expect(Code, Port, NAcc, ErrorMsg); _N -> ResponseCode = to_int(NAcc), if ResponseCode == Code -> ok; true -> throw({error, ErrorMsg}) end end; Err -> throw({error, Err}) end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% str2b64(String) -> str2b64(String, []). str2b64([], Acc) -> {[], lists:reverse(Acc)}; str2b64(String, Acc) -> case str2b64_line(String, []) of {ok, Line, Rest} -> str2b64(Rest, ["\n",Line|Acc]); {more, _} -> {String, lists:reverse(Acc)} end. % str2b64_final(String) -> str2b64_final(String, []). str2b64_final([], Acc) -> lists:reverse(Acc); str2b64_final(String, Acc) -> case str2b64_line(String, []) of {ok, Line, Rest} -> str2b64_final(Rest, ["\n",Line|Acc]); {more, Cont} -> lists:reverse(["\n",str2b64_end(Cont)|Acc]) end. % str2b64_line(S, []) -> str2b64_line(S, [], 0); str2b64_line(S, {Rest,Acc,N}) -> str2b64_line(Rest ++ S, Acc, N). str2b64_line(S, Out, 76) -> {ok,lists:reverse(Out),S}; str2b64_line([C1,C2,C3|S], Out, N) -> O1 = e(C1 bsr 2), O2 = e(((C1 band 16#03) bsl 4) bor (C2 bsr 4)), O3 = e(((C2 band 16#0f) bsl 2) bor (C3 bsr 6)), O4 = e(C3 band 16#3f), str2b64_line(S, [O4,O3,O2,O1|Out], N+4); str2b64_line(S, Out, N) -> {more,{S,Out,N}}. % str2b64_end({[C1,C2],Out,_N}) -> O1 = e(C1 bsr 2), O2 = e(((C1 band 16#03) bsl 4) bor (C2 bsr 4)), O3 = e((C2 band 16#0f) bsl 2), lists:reverse(Out, [O1,O2,O3,$=]); str2b64_end({[C1],Out,_N}) -> O1 = e(C1 bsr 2), O2 = e((C1 band 16#03) bsl 4), lists:reverse(Out, [O1,O2,$=,$=]); str2b64_end({[],Out,_N}) -> lists:reverse(Out); str2b64_end([]) -> []. % base64_2_str(Str) -> b642str(Str, 0, 0, []). b642str([$=|_], Acc, N, Out) -> case N of 2 -> %% If I have seen two characters before the = %% Them I'm encoding one byte lists:reverse([(Acc bsr 4)|Out]); 3 -> %% If I have seen three characters before the = %% Them I'm encoding two bytes B1 = Acc bsr 10, B2 = (Acc bsr 2) band 16#ff, lists:reverse([B2,B1|Out]); _ -> exit({bad,b64,N}) end; b642str([H|T], Acc, N, Out) -> case d(H) of no -> b642str(T, Acc, N, Out); I -> Acc1 = (Acc bsl 6) bor I, case N of 3 -> B1 = Acc1 bsr 16, B2 = (Acc1 band 16#ffff) bsr 8, B3 = (Acc1 band 16#ff), b642str(T, 0, 0, [B3,B2,B1|Out]); _ -> b642str(T, Acc1, N+1, Out) end end; b642str([], 0, 0, Out) -> lists:reverse(Out). d(X) when X >= $A, X =<$Z -> X - $A; d(X) when X >= $a, X =<$z -> X - $a + 26; d(X) when X >= $0, X =<$9 -> X - $0 + 52; d($+) -> 62; d($/) -> 63; d(_) -> no. e(X) when X >= 0, X < 26 -> X + $A; e(X) when X >= 26, X < 52 -> X + $a - 26; e(X) when X >= 52, X < 62 -> X + $0 - 52; e(62) -> $+; e(63) -> $/; e(X) -> erlang:error({badchar,X}). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% boundary_date() -> dat2str_boundary(yaws:date_and_time()). dat2str_boundary([Y1,Y2, Mo, D, H, M, S | _Diff]) -> lists:flatten( io_lib:format("~s_~2.2.0w_~s_~w_~2.2.0w:~2.2.0w:~2.2.0w_~w", [weekday(Y1,Y2,Mo,D), D, int_to_mt(Mo), y(Y1,Y2),H,M,S,bin2int(crypto:rand_bytes(4))])). bin2int(Bin) -> lists:foldl(fun(N, Acc) -> Acc * 256 + N end, 0, binary_to_list(Bin)). date_and_time_to_string(DAT) -> case validate_date_and_time(DAT) of true -> dat2str(DAT); false -> exit({badarg, {?MODULE, date_and_time_to_string, [DAT]}}) end. dat2str([Y1,Y2, Mo, D, H, M, S | Diff]) -> lists:flatten( io_lib:format("~s, ~2.2.0w ~s ~w ~2.2.0w:~2.2.0w:~2.2.0w", [weekday(Y1,Y2,Mo,D), D, int_to_mt(Mo), y(Y1,Y2),H,M,S]) ++ case Diff of [Sign,Hd,Md] -> io_lib:format("~c~2.2.0w~2.2.0w", [Sign,Hd,Md]); _ -> [] end). y(Y1, Y2) -> 256 * Y1 + Y2. weekday(Y1,Y2,Mo,D) -> int_to_wd(calendar:day_of_the_week(Y1*256+Y2,Mo,D)). int_to_wd(1) -> "Mon"; int_to_wd(2) -> "Tue"; int_to_wd(3) -> "Wed"; int_to_wd(4) -> "Thu"; int_to_wd(5) -> "Fri"; int_to_wd(6) -> "Sat"; int_to_wd(7) -> "Sun". int_to_mt(1) -> "Jan"; int_to_mt(2) -> "Feb"; int_to_mt(3) -> "Mar"; int_to_mt(4) -> "Apr"; int_to_mt(5) -> "May"; int_to_mt(6) -> "Jun"; int_to_mt(7) -> "Jul"; int_to_mt(8) -> "Aug"; int_to_mt(9) -> "Sep"; int_to_mt(10) -> "Oct"; int_to_mt(11) -> "Nov"; int_to_mt(12) -> "Dec". validate_date_and_time([Y1,Y2, Mo, D, H, M, S | Diff]) when 0 =< Y1, 0 =< Y2, 0 < Mo, Mo < 13, 0 < D, D < 32, 0 =< H, H < 24, 0 =< M, M < 60, 0 =< S, S < 61 -> case check_diff(Diff) of true -> calendar:valid_date(y(Y1,Y2), Mo, D); false -> false end; validate_date_and_time(_) -> false. check_diff([]) -> true; check_diff([$+, H, M]) when 0 =< H, H < 12, 0 =< M, M < 60 -> true; check_diff([$-, H, M]) when 0 =< H, H < 12, 0 =< M, M < 60 -> true; check_diff(_) -> false. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% to_string(Atom) when is_atom(Atom) -> atom_to_list(Atom); to_string(Integer) when is_integer(Integer) -> integer_to_list(Integer); to_string(List) -> List. format_error(Reason) -> [build_toolbar([{"","mail.yaws","Close"}]), {p, [], {font, [{size,4},{color,red}],["Error: ", Reason]}}]. format_message(Session, Message, MailNr, Depth) -> {HeadersList,Msg} = parse_message(Message), H = parse_headers(HeadersList), Headers = [[Head,$\n] || Head <- HeadersList], Formated = format_body(Session, H, Msg, Depth), Quoted = quote_format(Session, H, Msg), To = lists:flatten(decode(H#mail.to)), From = lists:flatten(decode(H#mail.from)), Subject = lists:flatten(decode(H#mail.subject)), CC = lists:flatten(decode(H#mail.cc)), ToolBar = if MailNr == -1 -> [{"tool-newmail.gif", "javascript:setCmd('reply');", "Reply"}]; MailNr == attachment -> [{"../tool-newmail.gif", "javascript:setCmd('reply');", "Reply"}]; true -> [{"tool-newmail.gif","compose.yaws","New"}, {"tool-newmail.gif", "javascript:setCmd('reply');", "Reply"}, {"","javascript:changeActive("++Depth++");", "<div id='msg-button:"++Depth++ "' style='display: block;'>Headers</div>" "<div id='hdr-button:"++Depth++ "' style='display: none;' >Message</div>" }, {"tool-delete.gif","javascript:setCmd('delete');", "Delete"}, {"","mail.yaws","Close"}] end, Action = if MailNr == attachment -> "../reply.yaws"; true -> "reply.yaws" end, [{form, [{name,compose},{action,Action},{method,post}], [build_toolbar(ToolBar), {table,[{width,645},{height,"100%"},{border,0},{bgcolor,silver}, {cellspacing,0},{callpadding,0}], {tr,[],{td,[{valign,top},{height,"1%"}], [{table, [{border,0},{cellspacing,0},{cellpadding,0},{width,"100%"}, {bgcolor,silver}], [{tr,[], [{td,[{valign,middle},{align,left},{width,"15%"}, {height,25}], {font, [{color,"#000000"},{size,2}], {nobr,[],"&nbsp;From:&nbsp;"}}}, {td, [{valign,middle},{align,left}], {font, [{color,"#000000"},{size,2}], ["&nbsp;", unquote(From)]}}, {td,[{valign,middle},{align,right},{height,"25"}], {font, [{color,"#000000"},{size,2}], {nobr,[],"&nbsp;Sent:&nbsp;"}}}, {td, [nowrap,{valign,middle},{align,right}, {width,"30%"}], {font, [{color,"#000000"},{size,2}], "&nbsp;"++H#mail.date}}]}, {tr,[], [{td,[{valign,top},{align,left},{width,"15%"}, {height,25}], {font, [{color,"#000000"},{size,2}], {nobr,[],"&nbsp;To:&nbsp;"}}}, {td, [{valign,top},{align,left},{width,"100%"}], {font, [{color,"#000000"},{size,2}], ["&nbsp;", unquote(To)]}}]}, {tr,[], [{td,[{valign,middle},{align,left},{width,"15%"}, {height,25}], {font, [{color,"#000000"},{size,2}], {nobr,[],"&nbsp;Cc:&nbsp;"}}}, {td, [{valign,middle},{align,left},{width,"100%"}], {font, [{color,"#000000"},{size,2}], ["&nbsp;",CC]}}]}, {tr,[], [{td,[{valign,middle},{align,left},{width,"15%"}, {height,25}], {font, [{color,"#000000"},{size,2}], {nobr,[],"&nbsp;Subject:&nbsp;"}}}, {td, [{valign,middle},{align,left},{width,"100%"}], {font, [{color,"#000000"},{size,2}], ["&nbsp;",Subject]}}]} ]}, {table, [{width,"100%"},{border,1},{cellpadding,6}, {class,msgbody}], [{tr,[], {td,[{width,"100%"},{height,300},{valign,top}, {bgcolor,white}], {p,[],{font,[{size,3},{id, contents}], [ {'div', [{id,"msg-body:msg"++Depth}, {class,"msg-body"}, {style,"display: block;"}], Formated }, {'div', [{id,"msg-body:hdr"++Depth}, {class,"msg-body"}, {style, "display: none;"}], {pre, [], Headers} } ] } } } } ] } ] } } }] ++ if MailNr == -1 -> []; true -> [{input,[{type,hidden},{name,nr}, {value,MailNr}],[]}] end++ [{input,[{type,hidden},{name,from}, {check,value,yaws_api:url_encode(From)}],[]}, {input,[{type,hidden},{name,to}, {check,value,yaws_api:url_encode(To)}],[]}, {input,[{type,hidden},{name,cc}, {check,value,yaws_api:url_encode(CC)}],[]}, {input,[{type,hidden},{name,bcc}, {check,value,yaws_api:url_encode(decode(H#mail.bcc))}],[]}, {input,[{type,hidden},{name,subject}, {check,value,yaws_api:url_encode(Subject)}],[]}, {input,[{type,hidden},{name,quote}, {check,value,yaws_api:url_encode(Quoted)}],[]}, {input,[{type,hidden},{name,cmd},{value,""}],[]} ] }]. select_alt_body([], [First|_]) -> First; select_alt_body([Prefered|Rest], Bodies) -> case [Body || Body <- Bodies, has_body_type(Prefered,Body)] of [] -> select_alt_body(Rest, Bodies); [First|_] -> First end. has_body_type(Type, {H,_B}) -> case H#mail.content_type of {CT, _Ops} -> CTL = lowercase(CT), CTL == Type; _ -> false end. format_body(Session, H, Msg, Depth) -> ContentType = case H#mail.content_type of {CT,Ops} -> {lowercase(CT), Ops}; Other -> Other end, case {ContentType,H#mail.transfer_encoding} of {{"text/html",_}, Encoding} -> Decoded = decode_message(Encoding, Msg), Decoded; {{"text/plain",_}, Encoding} -> Decoded = decode_message(Encoding, Msg), {pre, [], yaws_api:htmlize(wrap_text(Decoded, 80))}; {{"multipart/mixed",Opts}, _Encoding} -> {value, {_,Boundary}} = lists:keysearch("boundary",1,Opts), [{Headers,Body}|Parts] = parse_multipart(Msg, Boundary), PartHeaders = lists:foldl(fun({K,V},MH) -> add_header(K,V,MH) end, #mail{}, Headers), [format_body(Session, PartHeaders, Body, Depth++".1"), format_attachments(Session, Parts, Depth)]; {{"multipart/alternative",Opts}, _Encoding} -> {value, {_,Boundary}} = lists:keysearch("boundary",1,Opts), Parts = parse_multipart(Msg, Boundary), HParts = lists:map( fun({Head,Body}) -> NewHead = lists:foldl(fun({K,V},MH) -> add_header(K,V,MH) end, #mail{}, Head), {NewHead, Body} end, Parts), {H1,B1} = select_alt_body(["text/html","text/plain"],HParts), format_body(Session, H1,B1,Depth++".1"); {{"multipart/signed",Opts}, _Encoding} -> {value, {_,Boundary}} = lists:keysearch("boundary",1,Opts), [{Headers,Body}|_Parts] = parse_multipart(Msg, Boundary), PartHeaders = lists:foldl(fun({K,V},MH) -> add_header(K,V,MH) end, #mail{}, Headers), format_body(Session, PartHeaders, Body, Depth++".1"); {{"message/rfc822",_Opts}, Encoding} -> Decoded = decode_message(Encoding, Msg), format_message(Session, Decoded, -1, Depth); {{ContT="application/"++_,_Opts},Encoding} -> B1 = decode_message(Encoding, Msg), B = list_to_binary(B1), FileName = decode(extraxt_h_info(H)), Cookie = Session#session.cookie, mail_session_manager ! {session_set_attach_data, self(), Cookie, FileName, ContT, B}, receive {session_manager, Num} -> [{table,[{bgcolor, "lightgrey"}], [ {tr,[], {td, [], {h5,[], "Attachments:"}}}, {tr, [], {td, [], {table, [], [{tr,[], {td,[], {a, [{href,io_lib:format( "attachment/~s?nr=~w", [yaws_api:url_encode(FileName), Num])}], FileName}}}]}}}]}] after 10000 -> [] end; {_,_} -> {pre, [], yaws_api:htmlize(wrap_text(Msg, 80))} end. quote_format(Session, H, Msg) -> Text = quote_format_body(Session, H, Msg), From = lists:flatten(decode(H#mail.from)), include_quote(Text, From). quote_format_body(Session, H,Msg) -> ContentType = case H#mail.content_type of {CT,Ops} -> {lowercase(CT), Ops}; Other -> Other end, case {ContentType,H#mail.transfer_encoding} of {{"text/html",_}, Encoding} -> Decoded = decode_message(Encoding, Msg), wrap_text(mail_html:html_to_text(Decoded), 78); {{"text/plain",_}, Encoding} -> Decoded = decode_message(Encoding, Msg), wrap_text(Decoded, 78); {{"multipart/mixed",Opts}, _Encoding} -> {value, {_,Boundary}} = lists:keysearch("boundary",1,Opts), [{Headers,Body}|_Parts] = parse_multipart(Msg, Boundary), PartHeaders = lists:foldl(fun({K,V},MH) -> add_header(K,V,MH) end, #mail{}, Headers), quote_format_body(Session, PartHeaders, Body); {{"multipart/alternative",Opts}, _Encoding} -> {value, {_,Boundary}} = lists:keysearch("boundary",1,Opts), Parts = parse_multipart(Msg, Boundary), HParts = lists:map( fun({Head,Body}) -> NewHead = lists:foldl(fun({K,V},MH) -> add_header(K,V,MH) end, #mail{}, Head), {NewHead, Body} end, Parts), {H1,B1} = select_alt_body(["text/plain","text/html"], HParts), quote_format_body(Session, H1,B1); {{"multipart/signed",Opts}, _Encoding} -> {value, {_,Boundary}} = lists:keysearch("boundary",1,Opts), [{Headers,Body}|_Parts] = parse_multipart(Msg, Boundary), PartHeaders = lists:foldl(fun({K,V},MH) -> add_header(K,V,MH) end, #mail{}, Headers), quote_format_body(Session, PartHeaders, Body); {{"message/rfc822",_},_} -> ""; {{"application/"++_,_},_} -> ""; {_,_} -> wrap_text(Msg, 78) end. include_quote(Text, From) -> {Quoted, _} = include_quote(Text, [], ">", nl), From++" wrote: \n"++lists:reverse(Quoted). include_quote([], Acc, _Prefix, State) -> {Acc, State}; include_quote([L|Text], Acc, Prefix, State) when is_list(L) -> {Acc1, State1} = include_quote(L, Acc, Prefix, State), include_quote(Text, Acc1, Prefix, State1); include_quote(Text, Acc, Prefix, nl) -> case lists:prefix(Prefix, Text) of true -> include_quote(Text, Prefix++Acc, Prefix, body); false -> include_quote(Text, [$ |Prefix++Acc], Prefix, body) end; include_quote([$\n|Text], Acc, Prefix, body) -> include_quote(Text, [$\n|Acc], Prefix, nl); include_quote([C|Text], Acc, Prefix, body) -> include_quote(Text, [C|Acc], Prefix, body). format_attachments(_S, [], _Depth) -> []; format_attachments(S, Bs, Depth) -> [{table,[{bgcolor, "lightgrey"}], [ {tr,[], {td, [], {h5,[], "Attachments:"}}}, {tr, [], {td, [], {table, [], format_attach(S, Bs, Depth)}}}]}]. format_attach(_S, [], _Depth) -> []; format_attach(S, [{Headers,B0}|Bs], Depth) -> H = lists:foldl(fun({K,V},MH) -> add_header(K,V,MH) end, #mail{}, Headers), Cookie = S#session.cookie, FileName = decode(extraxt_h_info(H)), HttpCtype = case H#mail.content_type of undefined -> yaws_api:mime_type(FileName); {ContType,_Opts} -> case lowercase(ContType) of "text/"++_ -> yaws_api:mime_type(FileName); "application/octet-stream" -> yaws_api:mime_type(FileName); CT -> CT end; _ -> yaws_api:mime_type(FileName) end, B1 = decode_message(H#mail.transfer_encoding, B0), B = list_to_binary(B1), mail_session_manager ! {session_set_attach_data, self(), Cookie, FileName, HttpCtype, B}, receive {session_manager, Num} -> [{tr,[],{td,[], [{a, [{href,io_lib:format("attachment/~s?nr=~w", [yaws_api:url_encode(FileName), Num])}], FileName}, " (", {a, [{href,io_lib:format("attachment/~s?form=text&" "nr=~w", [yaws_api:url_encode(FileName), Num])}],"text"}, ")"]}} | format_attach(S, Bs, Depth)] after 10000 -> format_attach(S, Bs, Depth) end. extraxt_h_info(H) -> L = case {H#mail.content_type, H#mail.content_disposition} of {undefined, undefined} -> []; {undefined, {_, LL}} -> LL; {{_,LL}, undefined} -> LL; {{_,L1}, {_,L2}} -> L1 ++ L2 end, case lists:keysearch("filename", 1, L) of false -> "attachment.txt"; {value, {_, FN}} -> FN end. decode_message("7bit"++_, Msg) -> Msg; decode_message("8bit"++_, Msg) -> Msg; decode_message("base64"++_, Msg) -> case catch base64_2_str(lists:flatten(Msg)) of {'EXIT', _} -> Msg; Decoded -> Decoded end; decode_message("quoted-printable"++_, Msg) -> case catch quoted_2_str(lists:flatten(Msg)) of {'EXIT', Reason} -> io:format("failed to decode quoted-printable ~p\n", [Reason]), Msg; Decoded -> Decoded end; decode_message(_, Msg) -> Msg. quoted_2_str(Msg) -> quoted_2_str(Msg, []). quoted_2_str([], Acc) -> lists:reverse(Acc); quoted_2_str([$=,$\r,$\n|Rest], Acc) -> quoted_2_str_scan(Rest,Acc); quoted_2_str([$=,H1,H2|Rest], Acc) -> case catch yaws:hex_to_integer([H1,H2]) of {'EXIT', _} -> quoted_2_str(Rest, [H2,H1,$=|Acc]); C -> quoted_2_str(Rest, [C|Acc]) end; quoted_2_str([$\r,$\n|Rest], Acc) -> quoted_2_str_scan(Rest, [$\n|Acc]); quoted_2_str([C|Cs], Acc) -> quoted_2_str(Cs, [C|Acc]). quoted_2_str_scan([$ |Rest], Acc) -> quoted_2_str_scan(Rest, Acc); quoted_2_str_scan([$\t|Rest], Acc) -> quoted_2_str_scan(Rest, Acc); quoted_2_str_scan([$\v|Rest], Acc) -> quoted_2_str_scan(Rest, Acc); quoted_2_str_scan(Rest, Acc) -> quoted_2_str(Rest, Acc). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % parse_multipart(Data, Boundary) -> Res = parse_multipart(Data, Boundary, []), process_parts(Res, [], [], []). parse_multipart([], _State, Res) -> Res; parse_multipart([D|Ds], State, Res) -> case yaws_api:parse_multipart(D, State) of {cont, Cont, NewRes} -> parse_multipart(Ds, Cont, Res++NewRes); {result, NewRes} -> Res++NewRes end. process_parts([], [], [], Res) -> lists:reverse(Res); process_parts([{head,{Headers}}|Ps], [], [], Res) -> process_parts(Ps, Headers, [], Res); process_parts([{body,_B}|Ps], [], _Body, Res) -> % ignore headless body process_parts(Ps, [], [], Res); process_parts([{body,B}|Ps], Head, Body, Res) -> process_parts(Ps, [], [], [{Head, lists:reverse([B|Body])}|Res]); process_parts([{part_body,B}|Ps], Head, Body, Res) -> process_parts(Ps, Head, [B|Body], Res). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % The text to wrap may be arbitrarily nested. We deal with this % without flattening the whole thing. % wrap_text(Text, Max) -> wrap_text(Text, [], [], [], 0, Max, []). %% wrap_text(Text, ContText, PendingWord, PendingSpace, CurrentCol, WrapCol, Acc) wrap_text([], [], Unwrapped, Space, Col, Max, Acc) -> if Col < Max -> lists:reverse(Acc,add_space(Space,lists:reverse(Unwrapped))); true -> lists:reverse(Acc, [$\n|lists:reverse(Unwrapped)]) end; wrap_text([], Cont, Unwrapped, Space, Col, Max, Acc) -> wrap_text(Cont, [], Unwrapped, Space, Col, Max, Acc); wrap_text([L|Rest], [], Unwrapped, Space, Col, Max, Acc) when is_list(L) -> wrap_text(L, Rest, Unwrapped, Space, Col, Max, Acc); wrap_text([L|Rest], Cont, Unwrapped, Space, Col, Max, Acc) when is_list(L) -> wrap_text(L, [Rest|Cont], Unwrapped, Space, Col, Max, Acc); wrap_text([C|Rest], Cont, Unwrapped, Space, Col, Max, Acc) when Col < Max -> case char_class(C) of space -> wrap_text(Rest, Cont, [], C, Col+1, Max, Unwrapped++add_space(Space,Acc)); tab -> wrap_text(Rest, Cont, [], C, Col+8, Max, Unwrapped++add_space(Space,Acc)); nl -> wrap_text(Rest, Cont, [], [], 0, Max, [C|Unwrapped++add_space(Space,Acc)]); text -> wrap_text(Rest, Cont, [C|Unwrapped], Space, Col+1, Max, Acc) end; wrap_text([C|Rest], Cont, Unwrapped, Space, Col, Max, Acc) when Col >= Max -> case char_class(C) of space -> wrap_text(Rest, Cont, [], C, length(Unwrapped), Max, Unwrapped++[$\n|Acc]); tab -> wrap_text(Rest, Cont, [], C, length(Unwrapped), Max, Unwrapped++[$\n|Acc]); nl -> wrap_text(Rest, Cont, [], [], length(Unwrapped), Max, Unwrapped++[$\n|Acc]); text -> wrap_text(Rest, Cont, [C|Unwrapped], Space, Col+1, Max, Acc) end. add_space([], Text) -> Text; add_space(C, Text) -> [C|Text]. char_class($\n) -> nl; char_class($\r) -> nl; char_class($ ) -> space; char_class($\t) -> tab; char_class(_O) -> text. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sleep(X) -> receive xxxxxxx -> ok after X -> ok end. %%%%%%%%%%%%%%%%%%%%%% read cfg file %%%%%%%%%%%%%%%%%% %% def for root is: /etc/mail/yaws-webmail.conf -ifndef(ETCDIR). -define(ETCDIR, "/etc"). -endif. read_config() -> Paths = case yaws:getuid() of {ok, "0"} -> [?ETCDIR++"/mail/yaws-webmail.conf"]; _ -> [filename:join([os:getenv("HOME"),"yaws-webmail.conf"]), "./yaws-webmail.conf", ?ETCDIR++"/mail/yaws-webmail.conf"] end, case yaws:first(fun(F) -> yaws:exists(F) end, Paths) of false -> error_logger:info_msg("yaws webmail: Can't find no config file .. " "using defaults",[]), #cfg{}; {ok, _, File} -> read_config(File) end. read_config(File) -> error_logger:info_msg("Yaws webmail: Using config file ~s~n", [File]), case file:open(File, [read]) of {ok, FD} -> read_config(FD, #cfg{}, 1, io:get_line(FD, '')); _Err -> error_logger:info_msg("Yaws webmail: Can't open config file ... " "using defaults",[]), #cfg{} end. read_config(FD, Cfg, _Lno, eof) -> file:close(FD), Cfg; read_config(FD, Cfg, Lno, Chars) -> Next = io:get_line(FD, ''), case yaws_config:toks(Lno, Chars) of [] -> read_config(FD, Cfg, Lno+1, Next); ["ttl", '=', IntList] -> case (catch list_to_integer(IntList)) of {'EXIT', _} -> error_logger:info_msg("Yaws webmail: expect integer at " "line ~p", [Lno]), read_config(FD, Cfg, Lno+1, Next); Int -> read_config(FD, Cfg#cfg{ttl = Int}, Lno+1, Next) end; ["popserver", '=', Server] -> read_config(FD, Cfg#cfg{popserver = Server}, Lno+1, Next); ["smtpserver", '=', Domain] -> read_config(FD, Cfg#cfg{smtpserver = Domain}, Lno+1, Next); ["maildomain", '=', Domain] -> read_config(FD, Cfg#cfg{maildomain = Domain}, Lno+1, Next); ["sendtimeout", '=', IntList] -> case (catch list_to_integer(IntList)) of {'EXIT', _} -> error_logger:info_msg("Yaws webmail: expect integer at " "line ~p", [Lno]), read_config(FD, Cfg, Lno+1, Next); Int -> read_config(FD, Cfg#cfg{sendtimeout = Int}, Lno+1, Next) end; [H|_] -> error_logger:info_msg("Yaws webmail: Unexpected tokens ~p at " "line ~w", [H, Lno]), read_config(FD, Cfg, Lno+1, Next) end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -record(date, {year, month, day, hours, minutes, seconds}). parse_date([]) -> []; parse_date(Date) -> D = parse_date(Date, #date{}), if is_integer(D#date.year),is_integer(D#date.month), is_integer(D#date.day),is_integer(D#date.hours), is_integer(D#date.minutes),is_integer(D#date.seconds) -> {{D#date.year, D#date.month, D#date.day}, {D#date.hours, D#date.minutes, D#date.seconds}}; true -> error end. parse_date([], D) -> D; parse_date([D|Ds], Date) -> case char_type(D) of space -> parse_date(Ds, Date); alpha when Date#date.month == undefined -> case is_month(lowercase([D|Ds])) of false -> parse_date(Ds, Date); {true, M, Rest} -> parse_date(Rest, Date#date{month=M}) end; alpha -> parse_date(Ds, Date); digit -> case parse_time([D|Ds]) of error -> {Number,Rest} = get_number([D|Ds], 0), if Number < 32, Date#date.day == undefined -> parse_date(Rest, Date#date{day=Number}); Number < 50, Date#date.year == undefined -> parse_date(Rest, Date#date{year=Number+2000}); Number < 100, Date#date.year == undefined -> parse_date(Rest, Date#date{year=Number+1900}); Number > 1900, Date#date.year == undefined -> parse_date(Rest, Date#date{year=Number}); true -> parse_date(Rest, Date) end; {Hours, Minutes, Seconds, Rest} -> parse_date(Rest, Date#date{hours=Hours, minutes=Minutes, seconds=Seconds}) end; _ -> parse_date(Ds, Date) end. is_month("jan"++Rest) -> {true, 1, Rest}; is_month("feb"++Rest) -> {true, 2, Rest}; is_month("mar"++Rest) -> {true, 3, Rest}; is_month("apr"++Rest) -> {true, 4, Rest}; is_month("may"++Rest) -> {true, 5, Rest}; is_month("jun"++Rest) -> {true, 6, Rest}; is_month("jul"++Rest) -> {true, 7, Rest}; is_month("aug"++Rest) -> {true, 8, Rest}; is_month("sep"++Rest) -> {true, 9, Rest}; is_month("oct"++Rest) -> {true, 10, Rest}; is_month("nov"++Rest) -> {true, 11, Rest}; is_month("dec"++Rest) -> {true, 12, Rest}; is_month(_) -> false. enc_month(1) -> "Jan"; enc_month(2) -> "Feb"; enc_month(3) -> "Mar"; enc_month(4) -> "Apr"; enc_month(5) -> "May"; enc_month(6) -> "Jun"; enc_month(7) -> "Jul"; enc_month(8) -> "Aug"; enc_month(9) -> "Sep"; enc_month(10) -> "Oct"; enc_month(11) -> "Nov"; enc_month(12) -> "Dec". char_type(D) when D>=$a, D=<$z -> alpha; char_type(D) when D>=$A, D=<$Z -> alpha; char_type(D) when D>=$0, D=<$9 -> digit; char_type($\ ) -> space; char_type($\n) -> space; char_type($\t) -> space; char_type($\v) -> space; char_type(_) -> unknown. get_number([D|Ds], N) when D>=$0, D=<$9 -> get_number(Ds, N*10+(D-$0)); get_number(Rest, N) -> {N, Rest}. parse_time(Time) -> F = fun() -> {Hour,[$:|R1]} = get_number(Time, 0), {Minutes,[$:|R2]} = get_number(R1, 0), {Seconds,R3} = get_number(R2, 0), {Hour, Minutes, Seconds, R3} end, case catch F() of {Hour, Minutes, Seconds, Rest} when is_integer(Hour), is_integer(Minutes), is_integer(Seconds) -> {Hour, Minutes, Seconds, Rest}; _ -> error end. format_date({{Year,Month,Day},{Hour,Minutes,Seconds}}) -> M = enc_month(Month), io_lib:format("~2..0w ~s ~4..0w ~2..0w:~2..0w:~2..0w", [Day, M, Year, Hour, Minutes, Seconds]); format_date(Seconds) when is_integer(Seconds) -> Zero = calendar:datetime_to_gregorian_seconds({{1970,1,1},{0,0,0}}), Time = Zero + Seconds, Date = calendar:gregorian_seconds_to_datetime(Time), format_date(Date); format_date([]) -> []; format_date(error) -> []. send_attachment(Session, Number) -> mail_session_manager ! {session_get_attach_data, self(), Session#session.cookie, Number}, receive {session_manager, error} -> none; {session_manager, A} -> case A#satt.ctype of "message/rfc822" -> Message = binary_to_list(A#satt.data), Formated = format_message(Session, [Message], attachment, "1"), (dynamic_headers() ++ [{ehtml, [{script,[{src,"../mail.js"}], []}, {style, [{type,"text/css"}], ".conts { visibility:hidden }\n" "A:link { color: 0;text-decoration: none}\n" "A:visited { color: 0;text-decoration: none}\n" "A:active { color: 0;text-decoration: none}\n" "DIV.msg-body { background: white; }\n" }, {body,[{bgcolor,silver}, {marginheight,0},{topmargin,0},{leftmargin,0}, {rightmargin,0},{marginwidth,0}], [{table, [{border,0},{bgcolor,"c0c000"}, {cellspacing,0}, {width,"100%"}], {tr,[],{td,[{nowrap,true},{align,left}, {valign,middle}], {font, [{size,6},{color,black}], "Attachment"}}}}] ++ Formated } ]}]); _ -> {content, A#satt.ctype, A#satt.data} end after 15000 -> exit(normal) end. % send_attachment_plain(Session, Number) -> mail_session_manager ! {session_get_attach_data, self(), Session#session.cookie, Number}, receive {session_manager, error} -> none; {session_manager, A} -> {content, "text/plain", A#satt.data} after 15000 -> exit(normal) end. % basename(FilePath) -> case string:rchr(FilePath, $\\) of 0 -> %% probably not a DOS name filename:basename(FilePath); N -> %% probably a DOS name, remove everything after last \ basename(string:substr(FilePath, N+1)) end. %% getopt(Key, KeyList) -> getopt(Key, KeyList, undefined). getopt(Key, KeyList, Default) -> case lists:keysearch(Key, 1, KeyList) of false -> Default; {value, Tuple} -> Val = element(2,Tuple), if Val == undefined -> Default; true -> Val end end. %% content_type(FileName) -> case yaws_api:mime_type(FileName) of "text/plain" -> "application/octet-stream"; Type -> Type end. %% %% State = find_dot(Data, State) -> find_dot(State, Data, []). find_dot(State, [], _Acc) -> {more, State}; find_dot(0, [$\r|R], Acc) -> find_dot(1, R, [$\r|Acc]); find_dot(0, [C|R], Acc) -> find_dot(1, R, [C|Acc]); find_dot(1, [$\n|R], Acc) -> find_dot(2, R, [$\n|Acc]); find_dot(1, R, Acc) -> find_dot(0, R, Acc); find_dot(2, [$.|R], Acc) -> find_dot(3, R, [$\.|Acc]); find_dot(2, R, Acc) -> find_dot(0, R, Acc); find_dot(3, [$\r|R], Acc) -> find_dot(4, R, [$\r|Acc]); find_dot(3, R, Acc) -> find_dot(0, R, Acc); find_dot(4, [$\n|R], Acc) -> {ok, 0, lists:reverse(Acc), R}; find_dot(4, R, Acc) -> find_dot(0, R, Acc). ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/src/attachment.erl�����������������������������������������������������0000664�0001750�0001750�00000001553�12605311412�016453� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%------------------------------------------------------------------- %%% File : attachment.erl %%% Author : <klacke@hyber.org> %%% Description : %%% %%% Created : 4 Feb 2004 by <klacke@hyber.org> %%%------------------------------------------------------------------- -module(attachment). -compile(export_all). out(A) -> case mail:check_session(A) of {ok, Session} -> case {yaws_api:queryvar(A, "nr"),yaws_api:queryvar(A,"form")} of {{ok, Nr},{ok,"text"}} -> mail:send_attachment_plain(Session, yaws:to_integer(Nr)); {{ok, Nr},_} -> mail:send_attachment(Session, yaws:to_integer(Nr)); _ -> err() end; _Error -> err() end. err() -> [{status, 404}, {header, {connection, "close"}}]. �����������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/src/smtp.erl�����������������������������������������������������������0000664�0001750�0001750�00000021566�12605311412�015314� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������% -*- Erlang -*- % File: smtp.erl (~jb/work/yaws/applications/mail/src/smtp.erl) % Author: Johan Bevemyr % Created: Tue Feb 24 23:15:59 2004 % Purpose: -module('smtp'). -author('jb@bevemyr.com'). -export([send/6]). %% Example % % smtp:send("mail.bevemyr.com", "jb@bevemyr.com", % ["katrin@bevemyr.com","jb@bevemyr.com"], % "Test Subject", % "My Message", [{"file1.txt","text/plain","hej hopp igen"}]). % send(Server, From, To, Subject, Message, Attached) -> {ok, Port} = smtp_init(Server, From, To), Boundary="--Next_Part("++boundary_date()++")--", CommonHeaders = [mail_header("To: ", To), mail_header("From: ", From), mail_header("Subject: ", Subject)], Headers = case Attached of [] -> [mail_header("Content-Type: ", "text/plain"), mail_header("Content-Transfer-Encoding: ", "8bit")]; _ -> [mail_header("Mime-Version: ", "1.0"), mail_header("Content-Type: ", "Multipart/Mixed;\r\n boundary=\""++ Boundary++"\""), mail_header("Content-Transfer-Encoding: ", "8bit")] end, smtp_send_part(Port, [CommonHeaders, Headers, "\r\n"]), case Attached of [] -> ok; _ -> smtp_send_part(Port, ["--",Boundary,"\r\n", mail_header("Content-Type: ", "Text/Plain; charset=us-ascii"), mail_header("Content-Transfer-Encoding: ", "8bit"), "\r\n"]) end, smtp_send_message(Port, Message), case Attached of [] -> smtp_send_part(Port, ["\r\n.\r\n"]), smtp_close(Port); Files -> smtp_send_attachments(Port, Boundary, Files), smtp_send_part(Port, ["\r\n.\r\n"]), smtp_close(Port) end. smtp_send_attachments(Port, Boundary, []) -> smtp_send_part(Port, ["\r\n--",Boundary,"--\r\n"]); smtp_send_attachments(Port, Boundary, [{FileName,ContentType,Data}|Rest]) -> smtp_send_part(Port, ["\r\n--",Boundary,"\r\n", mail_header("Content-Type: ", ContentType), mail_header("Content-Transfer-Encoding: ", "base64"), mail_header("Content-Disposition: ", "attachment; filename=\""++ FileName++"\""), "\r\n" ]), smtp_send_b64(Port, Data), smtp_send_attachments(Port, Boundary, Rest). smtp_send_b64(Port, Data) -> B64 = str2b64_final(Data), gen_tcp:send(Port, B64). boundary_date() -> dat2str_boundary(calendar:local_time()). dat2str_boundary({{Y, Mo, D}, {H, M, S}}) -> lists:flatten( io_lib:format("~s_~2.2.0w_~s_~w_~2.2.0w:~2.2.0w:~2.2.0w_~w", [weekday(Y,Mo,D), D, int_to_mt(Mo), Y,H,M,S,bin2int(crypto:rand_bytes(4))])). bin2int(Bin) -> lists:foldl(fun(N, Acc) -> Acc * 256 + N end, 0, binary_to_list(Bin)). smtp_init(Server, From, Recipients) -> {ok, Port} = gen_tcp:connect(Server, 25, [{active, false}, {reuseaddr,true}, binary]), smtp_expect(220, Port, "SMTP server does not respond"), smtp_put( smtp_from(From), Port ), smtp_expect(250, Port, "Sender not accepted by mail server"), send_recipients(Recipients, Port), smtp_put("DATA", Port), smtp_expect(354, Port, "Message not accepted by mail server."), {ok, Port}. smtp_close(Port) -> smtp_put(".", Port), smtp_expect(250, Port, "Message not accepted by mail server."), gen_tcp:close(Port), ok. smtp_send_part(Port, Data) -> gen_tcp:send(Port, Data). smtp_send_message(Port, Data) -> {_LastNL, Escaped} = dot_escape(Data, true), gen_tcp:send(Port, Escaped). send_recipients( Recipients, Port ) -> Fun = fun (R) -> smtp_put( smtp_recipient(R), Port), smtp_expect(250, Port, io_lib:format("Recipient ~s not accepted.",[R])) end, lists:foreach( Fun, Recipients ). smtp_put(Message, Port) -> gen_tcp:send(Port, [Message,"\r\n"]). smtp_expect(Code, Port, ErrorMsg) -> smtp_expect(Code, Port, [], ErrorMsg). smtp_expect(Code, Port, Acc, ErrorMsg) -> Res = gen_tcp:recv(Port, 0, 15000), case Res of {ok, Bin} -> NAcc = Acc++binary_to_list(Bin), case string:chr(NAcc, $\n) of 0 -> smtp_expect(Code, Port, NAcc, ErrorMsg); _N -> ResponseCode = to_int(NAcc), if ResponseCode == Code -> ok; true -> throw({error, ErrorMsg}) end end; Err -> throw({error, Err}) end. %% add smtp from prelude. add <> around address (if needed) smtp_from( Address ) -> lists:append( "MAIL FROM: ", add_angle_brackets( Address ) ). %% add smtp recipients prelude. add <> around address (if needed) smtp_recipient( Address ) -> lists:append( "RCPT TO: ", add_angle_brackets( Address ) ). %% make sure the address has <> around itself add_angle_brackets( Address ) -> add_angle_bracket_start( add_angle_bracket_close(Address) ). add_angle_bracket_start( [$<|T] ) -> [$<|T]; add_angle_bracket_start( Address ) -> [$<|Address]. %% add > at the end of address, if it is not present add_angle_bracket_close( Address ) -> case lists:reverse( Address ) of [$>|_T] -> Address; Reversed -> lists:reverse( [$>|Reversed] ) end. %% Add an . at all lines starting with a dot. dot_escape(Data, NL) -> dot_escape(Data, NL, []). dot_escape([], NL, Acc) -> {NL, lists:reverse(Acc)}; dot_escape([$.|Rest], true, Acc) -> dot_escape(Rest, false, [$.,$.|Acc]); dot_escape([$\n|Rest], _, Acc) -> dot_escape(Rest, true, [$\n|Acc]); dot_escape([C|Rest], _, Acc) -> dot_escape(Rest, false, [C|Acc]). %% %dot_unescape(Data) -> % {_,Dt} = dot_unescape(Data, true, []), % Dt. % %dot_unescape([], NL, Acc) -> % {NL, lists:reverse(Acc)}; %dot_unescape([$.|Rest], true, Acc) -> % dot_unescape(Rest, false, Acc); %dot_unescape([$\n|Rest], _, Acc) -> % dot_unescape(Rest, true, [$\n|Acc]); %dot_unescape([L|Rest], NL, Acc) when list(L) -> % {NL2, L2} = dot_unescape(L, NL, []), % dot_unescape(Rest, NL2, [L2|Acc]); %dot_unescape([C|Rest], _, Acc) -> % dot_unescape(Rest, false, [C|Acc]). %% str2b64_final(String) -> str2b64_final(String, []). str2b64_final([], Acc) -> lists:reverse(Acc); str2b64_final(String, Acc) -> case str2b64_line(String, []) of {ok, Line, Rest} -> str2b64_final(Rest, ["\n",Line|Acc]); {more, Cont} -> lists:reverse(["\n",str2b64_end(Cont)|Acc]) end. %% str2b64_line(S, []) -> str2b64_line(S, [], 0); str2b64_line(S, {Rest,Acc,N}) -> str2b64_line(Rest ++ S, Acc, N). str2b64_line(S, Out, 76) -> {ok,lists:reverse(Out),S}; str2b64_line([C1,C2,C3|S], Out, N) -> O1 = e(C1 bsr 2), O2 = e(((C1 band 16#03) bsl 4) bor (C2 bsr 4)), O3 = e(((C2 band 16#0f) bsl 2) bor (C3 bsr 6)), O4 = e(C3 band 16#3f), str2b64_line(S, [O4,O3,O2,O1|Out], N+4); str2b64_line(S, Out, N) -> {more,{S,Out,N}}. %% str2b64_end({[C1,C2],Out,_N}) -> O1 = e(C1 bsr 2), O2 = e(((C1 band 16#03) bsl 4) bor (C2 bsr 4)), O3 = e((C2 band 16#0f) bsl 2), lists:reverse(Out, [O1,O2,O3,$=]); str2b64_end({[C1],Out,_N}) -> O1 = e(C1 bsr 2), O2 = e((C1 band 16#03) bsl 4), lists:reverse(Out, [O1,O2,$=,$=]); str2b64_end({[],Out,_N}) -> lists:reverse(Out); str2b64_end([]) -> []. %% e(X) when X >= 0, X < 26 -> X + $A; e(X) when X >= 26, X < 52 -> X + $a - 26; e(X) when X >= 52, X < 62 -> X + $0 - 52; e(62) -> $+; e(63) -> $/; e(X) -> erlang:error({badchar,X}). %% weekday(Y,Mo,D) -> int_to_wd(calendar:day_of_the_week(Y,Mo,D)). int_to_wd(1) -> "Mon"; int_to_wd(2) -> "Tue"; int_to_wd(3) -> "Wed"; int_to_wd(4) -> "Thu"; int_to_wd(5) -> "Fri"; int_to_wd(6) -> "Sat"; int_to_wd(7) -> "Sun". int_to_mt(1) -> "Jan"; int_to_mt(2) -> "Feb"; int_to_mt(3) -> "Mar"; int_to_mt(4) -> "Apr"; int_to_mt(5) -> "May"; int_to_mt(6) -> "Jun"; int_to_mt(7) -> "Jul"; int_to_mt(8) -> "Aug"; int_to_mt(9) -> "Sep"; int_to_mt(10) -> "Oct"; int_to_mt(11) -> "Nov"; int_to_mt(12) -> "Dec". %% mail_header(_Key, []) -> []; mail_header(Key, Val) -> Key++Val++"\r\n". %% to_int(Str) -> to_int(Str, 0). to_int([D|Ds], Acc) when D >= $0, D =< $9-> to_int(Ds, Acc*10+D-$0); to_int(_, Acc) -> Acc. %% ������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/src/mail_html.erl������������������������������������������������������0000664�0001750�0001750�00000020765�12605311412�016277� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������% -*- Erlang -*- % File: mail_html.erl % Author: Johan Bevemyr % Created: Sat Jun 19 15:13:49 2004 % Purpose: Transform HTML to text -module('mail_html'). -author('jb@mor.bevemyr.com'). -export([html_to_text/1]). html_to_text(Input) -> Tokens = tokenize(lists:flatten(Input), [], [], 1), Ehtml = parse(Tokens), RevText = ehtml_to_text(Ehtml, []), lists:reverse(RevText). ehtml_to_text([], Acc) -> Acc; ehtml_to_text([{Tag, _Opts}|Rest], Acc) -> Acc2 = add_tag_space(Tag, Acc), ehtml_to_text(Rest, Acc2); ehtml_to_text([{script, _Opts, _Body}|Rest], Acc) -> ehtml_to_text(Rest, Acc); ehtml_to_text([{Tag, _Opts, Body}|Rest], Acc) -> Acc1 = add_tag_space(Tag, Acc), Acc2 = ehtml_to_text(Body, Acc1), ehtml_to_text(Rest, Acc2); ehtml_to_text([Text|Rest], Acc) -> Text2 = text_reformat(Text, []), ehtml_to_text(Rest, [Text2|Acc]). add_tag_space(p, Acc) -> [$\n,$\r|Acc]; add_tag_space(br, Acc) -> [$\n,$\r|Acc]; add_tag_space(hr, Acc) -> [$\n,$\r|Acc]; add_tag_space(_, Acc) -> Acc. text_reformat([], Acc) -> lists:reverse(Acc); text_reformat([$\n|R], [$ |Acc]) -> text_reformat(R, Acc); text_reformat([$\n|R], Acc) -> text_reformat(R, [$ |Acc]); text_reformat([$\r|R], Acc) -> text_reformat(R, Acc); text_reformat([C|R], Acc) -> text_reformat(R, [C|Acc]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Alternative parser, recursive as hell %% parse(Tokens) -> parse(Tokens, []). parse([], Acc) -> lists:reverse(Acc); parse([{begin_tag, T, A, _L}|Rest], Acc) -> case tag_type(T) of leaf -> parse(Rest, [{T,A}|Acc]); node -> case find_body(T, Rest, []) of {error, _Reason} -> %% no body found, assume leaf %% io:format("Error: ~s on line ~p\n", [Reason, L]), parse(Rest, [{T,A}|Acc]); {Body,Rest2} -> ParsedBody = parse(Body), parse(Rest2, [{T,A,ParsedBody}|Acc]) end end; parse([{end_tag, _T, _A, _L}|Rest], Acc) -> %% errounous end tag, ignore parse(Rest, Acc); parse([{data, Data, _L}|Rest], Acc) -> parse(Rest, [Data|Acc]). find_body(Tag, [], _Acc) -> {error, "Missing end tag for "++atom_to_list(Tag)}; find_body(Tag, [{end_tag,Tag,_,_}|Rest], Acc) -> {lists:reverse(Acc),Rest}; find_body(Tag, [{begin_tag, Tag, A, L}|Rest], Acc) -> case find_body(Tag, Rest, []) of {error, Reason} -> %% no body found {error, Reason}; {Body, Rest1} -> find_body(Tag, Rest1, [{end_tag, Tag, [], -1}|lists:reverse(Body)++ [{begin_tag, Tag, A, L}|Acc]]) end; find_body(Tag, [X|Rest], Acc) -> find_body(Tag, Rest, [X|Acc]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %tag_type(option) -> leaf; tag_type(p) -> leaf; tag_type(hr) -> leaf; tag_type(input) -> leaf; tag_type(base) -> leaf; tag_type(img) -> leaf; tag_type('!doctype') -> leaf; tag_type(meta) -> leaf; tag_type(link) -> leaf; tag_type(br) -> leaf; tag_type(param) -> leaf; tag_type(_) -> node. % tokenize(Input, DataAcc, TokenAcc, LineNr) tokenize([], [], Tokens, _Line) -> lists:reverse(Tokens); tokenize([], Acc, Tokens, Line) -> lists:reverse([{data, lists:reverse(Acc), Line}|Tokens]); tokenize([$<,$!,$-,$-|R0], Acc, Tokens, L0) -> {R1, L1} = skip_comment(R0,L0), tokenize(R1, Acc, Tokens, L1); tokenize([$<|R0], Acc, Tokens, L0) -> {Tag,R1,L1} = scan_tag(R0,L0), if Acc == [] -> next_token(Tag, R1, [Tag|Tokens], L1); true -> Data = {data,lists:reverse(Acc),L0}, next_token(Tag, R1, [Tag,Data|Tokens], L1) end; tokenize([C=$\n|R0], Acc, Tokens, L) -> tokenize(R0, [C|Acc], Tokens, L+1); tokenize([C=$\r|R0], Acc, Tokens, L) -> tokenize(R0, [C|Acc], Tokens, L+1); tokenize([C|R0], Acc, Tokens, L) -> tokenize(R0, [C|Acc], Tokens, L). % next_token({begin_tag, script, _, _}, R, Tokens, L) -> {Data, R1, L1} = scan_endtag(R, "script", L), tokenize(R1, [], [{data, Data, L}|Tokens], L1); next_token({begin_tag, style, _, _}, R, Tokens, L) -> {Data, R1, L1} = scan_endtag(R, "style", L), tokenize(R1, [], [{data, Data, L}|Tokens], L1); next_token(_Tag, R, Tokens, L) -> tokenize(R, [], Tokens, L). %% '<' <id> <sp>+ [<id><sp>*['='<val>]]* ['/'] '>' scan_tag([$/|I], L) -> {_R0,L0} = skip_space(I, L), {Name,R1,L1} = scan_tag_name(I, L0), {R2,L2} = skip_space(R1, L1), {Args,R3,L3} = scan_tag_args(R2, L2), {{end_tag,list_to_atom(lowercase(Name)),Args,L0}, R3, L3}; scan_tag(I, L) -> {_R0,L0} = skip_space(I, L), {Name,R1,L1} = scan_tag_name(I, L0), {R2,L2} = skip_space(R1, L1), {Args,R3,L3} = scan_tag_args(R2, L2), {{begin_tag,list_to_atom(lowercase(Name)),Args,L0}, R3, L3}. % scan_tag_name(I, L) -> scan_token(I, [], L). % scan_tag_args(I, L) -> scan_tag_args(I, [], L). scan_tag_args([], Acc, L) -> {lists:reverse(Acc), [], L}; scan_tag_args([$>|R], Acc, L) -> {lists:reverse(Acc), R, L}; scan_tag_args(R=[$<|_], Acc, L) -> %% bad html {lists:reverse(Acc), R, L}; scan_tag_args(R0, Acc, L0) -> {Name,R1,L1} = scan_value(R0, L0), {R2, L2} = skip_space(R1, L1), case R2 of [$=|R3] -> {R4,L4} = skip_space(R3, L2), {Value,R5,L5} = scan_value(R4, L4), {R6,L6} = skip_space(R5, L5), OptName = list_to_atom(lowercase(Name)), scan_tag_args(R6, [{OptName,Value}|Acc], L6); _ -> scan_tag_args(R2, [Name|Acc], L2) end. % scan_value([$"|R], L) -> scan_quote(R, [], $", L); scan_value([$'|R], L) -> scan_quote(R, [], $', L); scan_value(R, L) -> scan_token(R, [], L). % scan_token([], Acc, L) -> {lists:reverse(Acc), [], L}; scan_token(R=[$>|_], Acc, L) -> {lists:reverse(Acc), R, L}; scan_token(R=[$<|_], Acc, L) -> %% bad html {lists:reverse(Acc), R, L}; scan_token(R=[$=|_], Acc, L) -> %% bad html {lists:reverse(Acc), R, L}; scan_token([C|R], Acc, L0) -> case char_class(C) of space -> {lists:reverse(Acc), R, L0}; nl -> {lists:reverse(Acc), R, L0+1}; _ -> scan_token(R, [C|Acc], L0) end. % scan_quote([], Acc, _Q, L) -> {lists:reverse(Acc), [], L}; scan_quote([Q|R], Acc, Q, L) -> {lists:reverse(Acc), R, L}; scan_quote([C=$\n|R], Acc, Q, L) -> scan_quote(R, [C|Acc], Q, L+1); scan_quote([C=$\r|R], Acc, Q, L) -> scan_quote(R, [C|Acc], Q, L+1); scan_quote([C|R], Acc, Q, L) -> scan_quote(R, [C|Acc], Q, L). % scan_endtag(R, Tag, L) -> scan_endtag(R, Tag, [], L). scan_endtag([], _Tag, Acc, L) -> {lists:reverse(Acc), [], L}; scan_endtag(R=[$<,$/|R0], Tag, Acc, L0) -> case casecmp(Tag, R0) of {true, R1} -> {R2,_} = skip_space(R1,L0), if hd(R2) == $> -> {lists:reverse(Acc), R, L0}; true -> scan_endtag(R0, Tag, Acc, L0) end; false -> scan_endtag(R0, Tag, Acc, L0) end; scan_endtag([C=$\n|R], Tag, Acc, L) -> scan_endtag(R, Tag, [C|Acc], L+1); scan_endtag([C=$\r|R], Tag, Acc, L) -> scan_endtag(R, Tag, [C|Acc], L+1); scan_endtag([C|R], Tag, Acc, L) -> scan_endtag(R, Tag, [C|Acc], L). % casecmp([], R) -> {true, R}; casecmp([C1|T1], [C2|T2]) -> C2low = lowercase_ch(C2), if C1 == C2low -> casecmp(T1,T2); true -> false end. % char_class($\n) -> nl; char_class($\r) -> nl; char_class($ ) -> space; char_class($\t) -> space; char_class(C) when C >= $a, C =< $z -> alpha; char_class(C) when C >= $A, C =< $Z -> alpha; char_class(C) when C >= $0, C =< $9 -> digit; char_class(_C) -> other. % skip_space([], L) -> {[], L}; skip_space(R = [C|R0], L) -> case char_class(C) of nl -> skip_space(R0, L+1); space -> skip_space(R0, L); _ -> {R, L} end. % skip_comment([], L) -> {[], L}; skip_comment([$-,$-,$>|R],L) -> {R,L}; skip_comment([$\n|R],L) -> skip_comment(R,L+1); skip_comment([$\r|R],L) -> skip_comment(R,L+1); skip_comment([_C|R],L) -> skip_comment(R,L). % lowercase(Str) -> [lowercase_ch(S) || S <- Str]. lowercase_ch(C) when C>=$A, C=<$Z -> C + 32; lowercase_ch(C) -> C. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% �����������yaws-2.0.2/applications/mail/src/Makefile.am��������������������������������������������������������0000664�0001750�0001750�00000001172�12605311412�015650� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include @top_srcdir@/include.mk MODULES = mail.erl attachment.erl smtp.erl mail_html.erl EXTRA_DIST = $(MODULES) defs.hrl EBIN_DIR=@builddir@/../ebin EBIN_FILES=$(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) -DETCDIR='"@sysconfdir@"' include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) clean-local: $(AM_V_at)rm -f $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/�������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�013730� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tool-delete.gif����������������������������������������������������0000664�0001750�0001750�00000000177�12605311412�016561� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��³�����¿���¿�¿¿���¿¿�¿�¿¿ÀÀÀ€€€ÿ���ÿ�ÿÿ���ÿÿ�ÿ�ÿÿÿÿÿ,�������4ðÈI«½8ëÍ»`h`X™dI¡œz°] {®7É£ýš³ÈöŸY.Õbj:‰ñ“l:ŸÐè$�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tab-right_inactive.gif���������������������������������������������0000664�0001750�0001750�00000001710�12605311412�020101� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��ç�����  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~€€€‚‚‚ƒƒƒ„„„………†††‡‡‡ˆˆˆ‰‰‰ŠŠŠ‹‹‹ŒŒŒŽŽŽ‘‘‘’’’“““”””•••–––———˜˜˜™™™ššš›››œœœžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥¦¦¦§§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³´´´µµµ¶¶¶···¸¸¸¹¹¹ººº»»»¼¼¼½½½¾¾¾¿¿¿ÀÀÀÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ØØØÙÙÙÚÚÚÛÛÛÜÜÜÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýþþþÿÿÿ!ù �þ�,�������¥�ãðádÍŸ?|æTEwО¹Hœ°Õ£Ç®žZôæ±3f§Ñ¼yé 2ô.^:f†ø¼{w²‘wíÌ1‹Ôæ;qÆ"ÙawÓ™%<ìÚ¥“†igLg¡Ú´cgΙ©æº!3…§›5iÈ`ÙéÖ ›4Xm̉³ŠË޹tâ¨õ³4j/;õ@Š Ö_=yæ8òÃg/$žÿðÍcfp`jm ãÃV0¿nq�;��������������������������������������������������������yaws-2.0.2/applications/mail/www/login.yaws���������������������������������������������������������0000664�0001750�0001750�00000001040�12605311412�015660� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> L = case (A#arg.req)#http_request.method of 'GET' -> yaws_api:parse_query(A); 'POST' -> yaws_api:parse_post(A) end, User = mail:getopt("user", L, ""), Passwd = mail:getopt("password", L, ""), case mail:login(User, Passwd) of {ok, Cookie} -> [yaws_api:setcookie("mailsession", Cookie), {redirect_local, {rel_path,"mail.yaws"}}]; {error, Reason} -> mail:display_login(A, Reason) end. </erl> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/mail.yaws����������������������������������������������������������0000664�0001750�0001750�00000001141�12605311412�015474� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case mail:check_session(A) of {ok, Session} -> L = yaws_api:parse_query(A), Refresh = case lists:keysearch("refresh",1,L) of {value, _} -> true; _ -> false end, Sort = case lists:keysearch("sort",1,L) of {value, {_,SortStr}} -> list_to_atom(SortStr); _ -> undefined end, mail:list(Session, {Refresh, Sort}); Error -> Error end. </erl> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tool-send.gif������������������������������������������������������0000664�0001750�0001750�00000000176�12605311412�016247� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��¢�����¿����¿ÀÀÀ€€€�ÿÿÿÿÿ���!ù���,�������CXºÜþ0ÊI«%8k .„!ŽäÐ9!9é º¶g“ x.ºË—Ê»šG”Óx p„ô žÐhó¨Z¯V‹vËíz �;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/send.yaws����������������������������������������������������������0000664�0001750�0001750�00000000242�12605311412�015504� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case mail:check_session(A) of {ok, Session} -> mail:send(Session,A); Error -> Error end. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/compose.yaws�������������������������������������������������������0000664�0001750�0001750�00000000243�12605311412�016221� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case mail:check_session(A) of {ok, Session} -> mail:compose(Session); Error -> Error end. </erl> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/logout.yaws��������������������������������������������������������0000664�0001750�0001750�00000000242�12605311412�016064� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case mail:check_session(A) of {ok, Session} -> mail:logout(Session); Error -> Error end. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/spacer.gif���������������������������������������������������������0000664�0001750�0001750�00000000052�12605311412�015611� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��€�����ÿÿÿ!ù���,�������L�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tab-bg_inactive.gif������������������������������������������������0000664�0001750�0001750�00000001624�12605311412�017360� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��÷�����  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~€€€‚‚‚ƒƒƒ„„„………†††‡‡‡ˆˆˆ‰‰‰ŠŠŠ‹‹‹ŒŒŒŽŽŽ‘‘‘’’’“““”””•••–––———˜˜˜™™™ššš›››œœœžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥¦¦¦§§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³´´´µµµ¶¶¶···¸¸¸¹¹¹ººº»»»¼¼¼½½½¾¾¾¿¿¿ÀÀÀÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ØØØÙÙÙÚÚÚÛÛÛÜÜÜÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýþþþÿÿÿ,�������y�ãıcgN~üú)ìw_ÆõìݳW¯½Šô2Ê›7O^Æxòä 2žIwñP¾[ùÎ]Ëwìb¶ƒ™²M›îr¾tù.Ë—ñº *®¨Ñ¢éÄ%Ç.]»˜ìäåD/#½yõæáÛÚ_¿­ÿúñûG¶¬Ù³hË�;������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tool-div.gif�������������������������������������������������������0000664�0001750�0001750�00000000062�12605311412�016072� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��‘��€€€�ÿÿÿÿÿ���!ù���,������� �;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/listop.yaws��������������������������������������������������������0000664�0001750�0001750�00000000467�12605311412�016076� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case mail:check_session(A) of {ok, Session} -> L = yaws_api:parse_post(A), Op = mail:get_val("cmd", L, ""), ToDelete = [M || {M,Op} <- L, Op=="yes"], mail:delete(Session, ToDelete); Error -> Error end. </erl> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/up.gif�������������������������������������������������������������0000664�0001750�0001750�00000000107�12605311412�014761� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a � �‘�����ÿÿÿfffÿÿÿ!ù���,���� � ��œ©‹À'€xØí\¶¯ÜmMçQæ‰2�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tab-hr.gif���������������������������������������������������������0000664�0001750�0001750�00000000653�12605311412�015520� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a,��Õ��ØÞéÏÖáÝäïÖÝè_k|ÊÒÞÚáëµ½ÈÔÜçÐØãßçò³¼ÇÇÐÛÖßêÆÎØâëöàéôÊÒÜÖÞèÉÒÜÈÑÛÍÖàØàéÊÔÞÉÓÝËÕßÏØá×àéÜæïËÖßñùÿòüÿõÿÿÿÿÿ������������������������������������������������������������������������������������������!ù��!�,����,���È@‚pH,H¤diÙ�,� BjH,‹¶a4$ÏåŠí:™Ëͦ¢ÑL:M¥SÉd&uz&©* rv‚s  x w” • ”’Ÿ…¢ž¡ ²´µ¶µ ¶³¹·¹¼¸µ—Å£ÇÆÇ««wÌžÆÏ¤¢ ààßæß  ääÞà óìóèà úú ýÿôô×`Aýýûç!�;�������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tool-newmail.gif���������������������������������������������������0000664�0001750�0001750�00000000213�12605311412�016742� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��¢�����¿����¿ÀÀÀ€€€�ÿÿÿÿÿ���!ù���,�������PXºÜþ0ʹˆ%´šm@&çI`(FÄ ®ìX]Wƒ«”H‚1× œ¡$2t €ÐÛ5¦NèyÂ:,jA(Z.ƒÖ˜íÁÝŒÞtfÍ~$��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/down.gif�����������������������������������������������������������0000664�0001750�0001750�00000000106�12605311412�015303� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a � �‘�����ÿÿÿfffÿÿÿ!ù���,���� � ��œ©Ë ˆU}—Á6P]#æi�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tab-right_active.gif�����������������������������������������������0000664�0001750�0001750�00000000550�12605311412�017553� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��Õ��38?ÃËÖxƒ>CIÍ×ãÁÊÕÀÈÒÝâèGMTmu~¦±½ÊÕáÈÓßÂÌׯÐÛÐ×ßÎÕÝ0AUfw¥´Ãƒ›˜¤°¢®º©µÁ¯»Ç¹Åѳ¾É·ÂÍÔßê×âíÄÎØÈÑÚËÔÝÑÙáÕÜãfghŒ™¥¬¹Å½ÉÔÅÏØT[aÏÝéÓÛâØßå·ÆÒÿÿÿ���������������������������������������������������!ù��.�,�������…@@@á*"„T‘µZHˆ"g"¹Œ"‡d�h*ÃPˆS"B M)A È©ʰ)¥HŸS}B8|{)z% $zŠ$%)&$& ’$ £'&v'%x-&± €$·-) '$*)A�;��������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tab-left_active.gif������������������������������������������������0000664�0001750�0001750�00000000555�12605311412�017375� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��Õ��'<Üàç38?ÃËÖxƒ>CIÍ×ãÁÊÕÄÌÖGMTmu~¦±½ÊÕáÂÌׯÐÛÐ×ßÎÕÝ0AUfw¥´Ãƒ›˜¤°¢®º©µÁ¯»Ç³¾É·ÂÍÔßêÒÝè×âíÈÒÜÄÎØÈÑÚËÔÝÑÙáÕÜ㌙¥¬¹Å½ÉÔÜèóÅÏØT[aÏÝéÏÛåÓÛâØßå·ÆÒÖÞäéééÿÿÿ������������������������������������!ù��3�,�������ŠÀÙŒA�f«€)"c ,¢—`²ÊH\±‰3Š”.‰t0qD£Ñ VæBß<T!ŠI“P©(| z( ! &(Š( ‰—&—–''• š¥šª(! '(* 0 ¿¼-0!,))A�;���������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/headers.yaws�������������������������������������������������������0000664�0001750�0001750�00000000346�12605311412�016173� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case mail:check_session(A) of {ok, Session} -> {ok, Nr} = queryvar(A, "nr"), mail:showheaders(Session, list_to_integer(Nr)); Error -> Error end. </erl> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/reply.yaws���������������������������������������������������������0000664�0001750�0001750�00000002256�12605311412�015715� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case mail:check_session(A) of {ok, Session} -> L = yaws_api:parse_post(A), Cmd = mail:get_val("cmd", L, reply), case Cmd of "reply" -> From = yaws_api:url_decode(mail:get_val("from", L, "")), Subject = yaws_api:url_decode(mail:get_val("subject", L, "")), To = yaws_api:url_decode(mail:get_val("to", L, "")), Cc = yaws_api:url_decode(mail:get_val("cc", L, "")), Bcc = yaws_api:url_decode(mail:get_val("bcc", L, "")), Quote = yaws_api:url_decode(mail:get_val("quote", L, "")), NewCc = if To == [] -> Cc; Cc == [] -> To; true -> To ++ ", " ++ Cc end, mail:compose(Session,"",From,NewCc,Bcc,"RE: "++Subject, Quote); "delete" -> Nr = mail:get_val("nr", L, ""), mail:delete(Session, [Nr]) end; Error -> Error end. </erl> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/index.yaws���������������������������������������������������������0000664�0001750�0001750�00000000106�12605311412�015661� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> {redirect_local, {rel_path, "mail.yaws"}}. </erl> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tab-bg_active.gif��������������������������������������������������0000664�0001750�0001750�00000000525�12605311412�017030� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��Õ��ìîòÜàçÃËÖÍ×ãÄÌÖÝâ覱½ÊÕáÈÓßÂÌׯÐÛÐ×ßÎÕÝ¢®º©µÁ¯»Ç¹Åѳ¾É·ÂÍÔßêÒÝè×âíÈÒÜÄÎØÈÑÚËÔÝÑÙáÕÜ㬹ŽÉÔÜèóÅÏØÏÛåÓÛâÖÞäÿÿÿ���������������������������������������������������������������������������������!ù��$�,�������r@€p( ƒÒ0ŒžOG4ÝX©›FCÃ`h·Zf¡¹˜A  (* ÖƒE»aîvL´¸`Ø u†‰ŠŒ“‘›œ Ÿž  !!«!°´·¸A�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/view-mark.gif������������������������������������������������������0000664�0001750�0001750�00000000125�12605311412�016237� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a � �‘�����ÀÀÀ€€€ÿÿÿ!ù�����,���� � ��&”í´ÖÈlxê6tƒ7‚"èPçsITÚf¯&jq„çú®�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/showmail.yaws������������������������������������������������������0000664�0001750�0001750�00000000433�12605311412�016400� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> case mail:check_session(A) of {ok, Session} -> L = yaws_api:parse_query(A), {value, {_,Nr}} = lists:keysearch("nr",1,L), mail:showmail(Session, list_to_integer(Nr)); Error -> Error end. </erl> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/mail.js������������������������������������������������������������0000664�0001750�0001750�00000007015�12605311412�015133� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- Java -*- * * File: mail.js * Author: Johan Bevemyr * Created: Sun Feb 15 23:40:56 2004 * Purpose: support functions for webmail */ function setCmd(val) { if (val == 'delete') { var msg = 'Are you sure you want to delete this message?'; if (!confirm(msg)) return; } document.compose.cmd.value=val; document.compose.submit(); } function changeActive(depth) { var msg = document.getElementById('msg-body:msg'+depth); var hdr = document.getElementById('msg-body:hdr'+depth); var bm = document.getElementById('msg-button:'+depth); var bh = document.getElementById('hdr-button:'+depth); if (msg.style.display == 'block') { msg.style.display = 'none'; hdr.style.display = 'block'; bm.style.display = 'none'; bh.style.display = 'block'; } else { msg.style.display = 'block'; hdr.style.display = 'none'; bm.style.display = 'block'; bh.style.display = 'none'; } } function setComposeCmd(val) { if (document.compose.to.value.length == 0) { alert('The To: field must not be empty.'); document.compose.to.focus(); return; } try { document.compose.message.value = editor.getHTML(); } catch (e) { var rExp; var text=document.compose.html_message.value; rExp=/&aring;/gi; text.replace(rExp, "å"); rExp=/&aring;/gi; text.replace(rExp, "Å"); document.compose.message.value = text; } // alert(editor.getHTML()); if (document.compose.message.value.length == 0) { alert('The message field must not be empty.'); document.compose.html_message.focus(); return; } /* check for attachements */ if (document.compose.file1.value.length > 0) { document.compose.attached.value="yes"; } else if (document.compose.file2.value.length > 0) { document.compose.attached.value="yes"; } else if (document.compose.file3.value.length > 0) { document.compose.attached.value="yes"; } else if (document.compose.file4.value.length > 0) { document.compose.attached.value="yes"; } else if (document.compose.file5.value.length > 0) { document.compose.attached.value="yes"; } else if (document.compose.file6.value.length > 0) { document.compose.attached.value="yes"; } else if (document.compose.file7.value.length > 0) { document.compose.attached.value="yes"; } else if (document.compose.file8.value.length > 0) { document.compose.attached.value="yes"; } else if (document.compose.file9.value.length > 0) { document.compose.attached.value="yes"; } else if (document.compose.file10.value.length > 0) { document.compose.attached.value="yes"; } document.compose.cmd.value=val; document.compose.submit(); } function changeActiveTab(i) { var j; for( j=0; j < tabCount; ++j ) { if( i==j ) { activateTab(j); } else { deactivateTab(j); } } } function activateTab(i) { document.getElementById( "tab-left:"+i ).src="tab-left_active.gif"; document.getElementById( "tab-bg:"+i ).style.background="url(tab-bg_active.gif)"; document.getElementById( "tab-right:"+i ).src="tab-right_active.gif"; document.getElementById( "tab-body:"+i ).style.display='block'; } function deactivateTab(i) { document.getElementById( "tab-left:"+i ).src="tab-left_inactive.gif"; document.getElementById( "tab-bg:"+i ).style.background="url(tab-bg_inactive.gif)"; document.getElementById( "tab-right:"+i ).src="tab-right_inactive.gif"; document.getElementById( "tab-body:"+i ).style.display='none'; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/www/tab-left_inactive.gif����������������������������������������������0000664�0001750�0001750�00000001700�12605311412�017715� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��ç�����  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~€€€‚‚‚ƒƒƒ„„„………†††‡‡‡ˆˆˆ‰‰‰ŠŠŠ‹‹‹ŒŒŒŽŽŽ‘‘‘’’’“““”””•••–––———˜˜˜™™™ššš›››œœœžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥¦¦¦§§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³´´´µµµ¶¶¶···¸¸¸¹¹¹ººº»»»¼¼¼½½½¾¾¾¿¿¿ÀÀÀÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ØØØÙÙÙÚÚÚÛÛÛÜÜÜÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýþþþÿÿÿ!ù �þ�,��������ýùãÄ'N‘"a«ÇÓ iôîݳcJܼzöðKo½AÈ8zLÄ,Ý;yò13ç.Þ»H%Ùµ{éLœÌv˜˜Ùl玓4›ìØ…’f.¨;SÎXš4¥Ì¦»w­YÃÖ­,iUʼn«E­›8sâpyM—Ž]°neÙ¹ æ4^=dæäñãWÏ;|üþñ“f/ï¿Öìýý‹Mðàn~ÿ�;����������������������������������������������������������������yaws-2.0.2/applications/mail/yaws-webmail.conf������������������������������������������������������0000664�0001750�0001750�00000000771�12605311412�016301� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This is the default Yaws webmail configuration file # It contains very few config items, ... # The time to live, a session is GC'ed by the server # when it has ben idle for more than this amount of seconds ttl = 1800 # the popserver, either an IP or a FQDN is acceptable here popserver = localhost # same goes for the smtp server smtpserver = localhost ## maildomin must be set, maildomain = mydomain.org # The timeout in send operations, default should be fine here (ms) sendtimeout = 15000 �������yaws-2.0.2/applications/mail/TODO�������������������������������������������������������������������0000664�0001750�0001750�00000001266�12605311412�013521� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Things to do - handle attachments in received emails - optionally include old text as quoted text in reply. We need to select the text part for the quote if the email is of type multipart/alternative. We select text/html to display. - page large inboxes with 20 emails per page (sorted in reverse order with most recently received emails first) - write an attachement cache to limit the delays when fetching an attachement - code outgoing emails as quoted-printable (must limit max line length to 74 according to RFC ???) - Sort by 'From', 'Subject' and 'Nr' - Implement mail forwarding - Support imap mail backend system. - Properly decode encoded attachments. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/mail/Makefile.am������������������������������������������������������������0000664�0001750�0001750�00000001316�12605311412�015061� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������SUBDIRS = src ebin EXTRA_DIST = yaws-webmail.conf TODO README www INSTDIR=$(DESTDIR)$(appsdir)/mail install-data-local: $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(sysconfdir)/mail $(AM_V_at)if [ -f $(DESTDIR)$(sysconfdir)/mail/yaws-webmail.conf ]; then \ echo "$(DESTDIR)$(sysconfdir)/mail/yaws-webmail.conf already exists"; \ else \ $(INSTALL) -m 644 @srcdir@/yaws-webmail.conf $(DESTDIR)$(sysconfdir)/mail; \ fi $(AM_V_at)$(INSTALL) -d $(INSTDIR) $(AM_V_at)(cd @srcdir@; tar cf - www ) | (cd $(INSTDIR); tar xf - ) $(AM_V_at)chmod -R u+rw $(INSTDIR)/www uninstall-local: $(AM_V_at)rm -f $(DESTDIR)$(sysconfdir)/mail/yaws-webmail.conf $(INSTDIR)/www # Local Variables: # tab-width: 8 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12605312016�013132� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/Makefile.in������������������������������������������������������������0000664�0001750�0001750�00000053511�12605311445�015133� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/yapp DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ SUBDIRS = src ebin EDOC_OPTS = [{def,{vsn,"@YAPP_VSN@"}}, {source_path, ["@srcdir@"]}, {packages, false}] EXTRA_DIST = vsn.mk README priv examples all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/yapp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/yapp/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-local 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 installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-local install-data-local: docs $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp) $(AM_V_at)(cd @srcdir@; tar cf - priv examples ) | (cd $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp); tar xf - ) $(AM_V_at)(cd @builddir@; tar cf - doc ) | (cd $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp); tar xf - ) $(AM_V_at)if test $(yappdir) != $(ERLANG_INSTALL_LIB_DIR_yapp); then \ $(INSTALL) -d $(DESTDIR)$(libdir); \ rm -f $(DESTDIR)$(libdir)/yapp; \ $(LN_S) -f $(ERLANG_INSTALL_LIB_DIR_yapp) $(DESTDIR)$(libdir)/yapp; \ fi uninstall-local: $(AM_V_at)rm -fr $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp)/doc $(AM_V_at)rm -fr $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp)/priv $(AM_V_at)rm -fr $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp)/examples $(AM_V_at)[ ! -h $(yappdir) ] || rm -f $(DESTDIR)$(libdir)/yapp docs: $(AM_V_at)$(MKDIR_P) doc $(AM_V_at)$(ERL) -noshell -run edoc_run application "'yapp'" '"."' '$(EDOC_OPTS)' -s init stop clean-local: $(AM_V_at)rm -rf doc # Local Variables: # tab-width: 8 # End: # 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: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/priv/������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�014113� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/priv/docroot/����������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�015564� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/priv/docroot/remove.yaws�����������������������������������������������0000664�0001750�0001750�00000002624�12605311412�017712� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> {ssi, "HEAD.inc","%%",[{"remove", "choosen"}]}. </erl> <h3>Remove yapp</h3> <form action="remove_post.yaws" method="post"> <erl> format_yapp_tables([]) -> []; format_yapp_tables([ServId|T]) -> Yapps = yapp_handler:list(yapp_handler,ServId), [ format_yapp_table(ServId, Yapps) | format_yapp_tables(T)]. format_yapp_table(ServId, undefined) -> ""; format_yapp_table(ServId, Yapps) -> ["<h3> Server id : ", ServId, "</h3>", "<table border=\"1\"><tr><th>Select</th><th>Application</th><th>Url</th></tr>", format_yapps(ServId, Yapps), "<table>"]. format_yapps(ServId,[]) -> []; format_yapps(ServId, [{Urlpath, Appname}|T]) -> ["<tr><td>", "<input type=\"radio\" name=\"srvidurlpath\" value=\"", ServId,",",Urlpath, "\" />", "</td><td>", atom_to_list(Appname), "</td><td>", Urlpath, "</td></tr>" | format_yapps(ServId, T)]. out(A) -> Header = "Cache-Control:no-store", [{header,Header},{html, format_yapp_tables(yapp:get_server_ids())}]. </erl> <p> <input type="submit" value="Remove Yapp"> </p> </form> <p>The Yapps listed in this page are those stored in the Yapp registry. It excludes the applications loaded from yaws.conf with the bootstrap_yapps opaque variable. It will also include those registered applications that are not available in the Erlang load path, and therefore not shown on the "List" page.</p> <erl> out(A) -> {ssi,"END.inc",[],[]}. </erl> ������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/priv/docroot/HEAD.inc��������������������������������������������������0000664�0001750�0001750�00000001461�12605311412�016702� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta name="keywords" content="Yaws"/> <title>Yapp</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> <link rel="stylesheet" type="text/css" href="stil.css"/> <link rel="shortcut icon" href="/icons/yaws_y.gif" type="image/x-icon"/> </head> <body> <div class="logo"> <img src="/icons/yaws_head.gif" width="600" alt="YAWS"/> </div> <div id="sidebar"> <h4> Yapp </h4> <div class="%%list%%"> <a href="index.yaws" id="list">List</a></div> <div class="%%add%%"> <a href="add.yaws" id="Add" >Add</a> </div> <div class="%%remove%%"> <a href="remove.yaws" id="remove">Remove</a> </div> </div> <div id="entry"> <h2>Yapp admin console</h2> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/priv/docroot/END.inc���������������������������������������������������0000664�0001750�0001750�00000000027�12605311412�016604� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������</div> </body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/priv/docroot/stil.css��������������������������������������������������0000664�0001750�0001750�00000003206�12605311412�017172� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ html {margin: 0; padding: 0;} body {font: 12px Verdana, Arial, Helvetica, sans-serif; margin: 0; padding: 0; background: rgb(95%,95%,95%); color: black;} h1 {font-size: 200%; text-transform: lowercase; letter-spacing: 3px; margin: 0.66em 0 0.33em 3%; padding: 0;} h3 {font-size: 133%; margin: 10; padding: 10; border-bottom: 1px solid black;} h4 {font-size: 100%; margin: 0; padding: 0.33em 0 0; border-bottom: 1px solid rgb(50%,50%,35%); color: rgb(50%,50%,35%);} h5 {font-size: 100%; margin: 0; padding: 0.33em 0 0; color: rgb(50%,50%,35%);} p {line-height: 1.66; margin: 0.5em 0 1em 3em;} div.logo {margin: 3em;} div#entry {margin: 0 33% 1em 7%; padding: 0;} div#sidebar {position: absolute; top: 4em; right: 0; width: 20%; font-size: 11px;} div#sidebar a {display: block; padding: 8px 0 2px 10px; margin: 0; border-left: 1px solid rgb(50%,50%,35%);} div#sidebar a:hover {background: rgb(221,221,221);} div.links { background: green; } div.box { border: solid; border-width: thin; width: 96%; background: rgb(211, 211, 211) } div.news { border: solid; border-width: thin; width: 96%; border-bottom: 3px solid black; margin: 18px 5px 2px 10px; background: rgb(211, 211, 211) } div.box pre {margin: 0.66em 0 0.33em 1%; padding: 0;} div.man { border: solid; border-width: thin; width: 100%; font-size: 90%; margin : 4; background: rgb(211,211,211) } div.choosen {border: solid; border-width: thin; background: rgb(231, 231, 231) } div.none { } I { font-size : 12px; font-family: Times, Verdana, Arial, Helvetica, sans-serif;} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/priv/docroot/add.yaws��������������������������������������������������0000664�0001750�0001750�00000002427�12605311412�017146� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> {ssi, "HEAD.inc","%%",[{"add", "choosen"}]}. </erl> <h3>Add yapp</h3> <form action="add_post.yaws" method="post"> <p> <erl> format_srvid_radio([]) -> []; format_srvid_radio([ServId|T]) -> [ "<br />", "<input type=\"radio\" name=\"srvid\" value=\"", ServId, "\" />", ServId | format_srvid_radio(T)]. out(A) -> Header = "Cache-Control:no-store", [{header, Header}, {html, [ "Server id: ", format_srvid_radio(yapp:get_server_ids())]}]. </erl> </p> <p>Application name: <input type="textfield" name="appname"></p> <p>Path (optional) : <input type="textfield" name="path"></p> <p><input type="submit" value="Add Yapp"></p> </form> <p><em>Note:</em> An added Yapp will always be stored in the registry, but if the application is not really in the load path of the Erlang system it will not be loaded into Yaws server configuration. In such case it will not show up the when listing the applications in the Yapp console, but it will show up in the Remove list.</p> <p>If the yapp handler fails to find the application, a record will be written to the error log. The application may be included in the load path later, and will be put into Yaws configuration when Yaws is hupped or next time a Yapp is added/removed.</p> <erl> out(A) -> {ssi,"END.inc",[],[]}. </erl> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/priv/docroot/remove_post.yaws������������������������������������������0000664�0001750�0001750�00000002137�12605311412�020756� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> {ssi, "HEAD.inc","%%",[{"remove", "choosen"}]}. </erl> <h3>Add yapp</h3> <erl> get_value(K,P) -> case proplists:get_value(K,P) of undefined -> {"",""}; V -> [ServId,Path|_] = string:tokens(string:strip(V),","), {string:strip(ServId), string:strip(Path)} end. format(P) -> {SrvId,UrlPath} = get_value("srvidurlpath",P), format(SrvId,UrlPath). format([],_) -> error(no_srv_id); format(_,[]) -> error(no_path); format(S,P) -> case yapp_handler:remove(yapp_handler, S, P) of ok -> ["Removed Server Id: ", S,", Path: ", P]; Error -> error(Error) end. error(no_srv_id) -> "<p>No Server Id selected!</p>"; error(no_path) -> "<p>No path given!</p>"; error(E) -> ["<p>Error removing yapp<pre>",E,"</pre></p>"]. out(A) -> P = yaws_api:parse_post(A), Header = "Cache-Control:no-store", [{header, Header}, {html, ["<p>",format(P),"</p>", "<a href=\"remove.yaws\"> Return to remove page</a>"] }, {ssi,"END.inc",[],[]}]. </erl>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/priv/docroot/index.yaws������������������������������������������������0000664�0001750�0001750�00000001465�12605311412�017526� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <erl> out(A) -> {ssi, "HEAD.inc","%%",[{"list", "choosen"}]}. </erl> <h3>Yapp list</h3> <erl> format_yapp_tables([]) -> []; format_yapp_tables([{ServId,Yapps}|T]) -> [{h3,[], ["Server id : ", ServId]}, [{p,[],format_yapp_table(Yapps)}] | format_yapp_tables(T)]. format_yapp_table(Yapps) -> {table,[{border,"1"}], [{tr,[],[{th,[],"Application"},{th,[],"Url"},{th,[],"Docroot"}]} | format_yapps(Yapps)] }. format_yapps([]) -> []; format_yapps([{yapp, Urlpath, Docroot, Appname, Appmods, _Opaque}|T]) -> [{tr,[],[{td,[],atom_to_list(Appname)}, {td,[], Urlpath},{td,[],Docroot}]} | format_yapps(T)]. out(A) -> Header = "Cache-Control:no-store", [{header, Header}, {ehtml, format_yapp_tables(yapp:get_yapps())}]. </erl> <erl> out(A) -> {ssi,"END.inc",[],[]}. </erl> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/priv/docroot/add_post.yaws���������������������������������������������0000664�0001750�0001750�00000002152�12605311412�020206� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<erl> out(A) -> {ssi, "HEAD.inc","%%",[{"add", "choosen"}]}. </erl> <h3>Add yapp</h3> <erl> get_value(K,P) -> case proplists:get_value(K,P) of undefined -> ""; V -> string:strip(V) end. format(P) -> SrvId = get_value("srvid",P), AppName = get_value("appname",P), Path = get_value("path",P), format(SrvId,AppName,Path). format([],_,_) -> error(no_srv_id); format(_,[],_) -> error(no_appname); format(S,A,[]) -> format(S,A,"/" ++ A); format(S,A,P) -> case (catch yapp_handler:add(yapp_handler, S, P, list_to_atom(A))) of ok -> ["Added Server Id: ", S,", AppName: ", A, ", Path: ", P]; Error -> error(Error) end. error(no_srv_id) -> "<p>No Server Id selected!</p>"; error(no_appname) -> "<p>No AppName given!</p>"; error(E) -> ["<p>Error adding yapp<pre>", io:format("~p",[E]),"</pre></p>"]. out(A) -> P = yaws_api:parse_post(A), {html, ["<p>",format(P),"</p>"] }. </erl> <p><a href="add.yaws">Return to add page</a></p> <erl> out(A) -> {ssi,"END.inc",[],[]}. </erl> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/README�����������������������������������������������������������������0000664�0001750�0001750�00000001472�12605311412�013737� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������An easy way to deploy Yaws applications (Yapps) independently of each other. To compile : make Generate edoc documents : make docs Install: make install You need to have compiled (configured) the Yaws application before making yapp. See the generated documents for more info in how to use the yapp application. The current application uses mnesia so a precondition is that a schema is generated for the node Yaws is running on. Known problems - You need a trailing "/" to your path when doing directory based access to the yapp. TODO - subscribe on mnesia events so that the yapp registry can be updated and used in a cluster of yaws nodes. - Support to create .boot and relup scripts so that Yapps can be added/upgraded/downgraded/removed on a running Yaws server. - Cluster support for the point above. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/ebin/������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312016�014051� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/ebin/Makefile.in�������������������������������������������������������0000664�0001750�0001750�00000041401�12605311445�016043� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/yapp/ebin DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(beamdir)" DATA = $(beam_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ beamdir = $(ERLANG_INSTALL_LIB_DIR_yapp)/ebin APP_FILES = yapp.app yapp.appup BEAM_FILES = *.beam beam_DATA = $(APP_FILES) $(BEAM_FILES) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/yapp/ebin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/yapp/ebin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-beamDATA: $(beam_DATA) @$(NORMAL_INSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(beamdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(beamdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(beamdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(beamdir)" || exit $$?; \ done uninstall-beamDATA: @$(NORMAL_UNINSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(beamdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(beamdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-beamDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-beamDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-beamDATA install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-beamDATA clean-local: $(AM_V_at)rm -f $(APP_FILES) $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: # 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: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/ebin/Makefile.am�������������������������������������������������������0000664�0001750�0001750�00000000363�12605311412�016026� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������beamdir = $(ERLANG_INSTALL_LIB_DIR_yapp)/ebin APP_FILES = yapp.app yapp.appup BEAM_FILES = *.beam beam_DATA = $(APP_FILES) $(BEAM_FILES) clean-local: $(AM_V_at)rm -f $(APP_FILES) $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/�������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312016�013723� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/Makefile.in��������������������������������������������������������0000664�0001750�0001750�00000040317�12605311445�015722� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = applications/yapp/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = yapp_app.erl \ yapp.erl \ yapp_ets_server.erl \ yapp_event_handler.erl\ yapp_handler.erl \ yapp_mnesia_server.erl\ yapp_registry.erl \ yapp_server.erl \ yapp_sup.erl EXTRA_DIST = $(MODULES) yapp.app.src yapp.appup.src EBIN_DIR = @builddir@/../ebin EBIN_FILES = $(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign applications/yapp/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign applications/yapp/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_DIR)/yapp.app $(EBIN_DIR)/yapp.appup $(EBIN_FILES) clean-local: $(AM_V_at)rm -f $(EBIN_DIR)/yapp.app $(EBIN_DIR)/yapp.appup $(EBIN_FILES) $(EBIN_DIR)/yapp.app: @srcdir@/yapp.app.src $(AM_V_GEN)$(AWK) -v src="$(MODULES)" \ "/{vsn, *{cmd,/ { \ line = \$$0; \ sub(/{vsn.*/, \"{vsn, \\\"@YAPP_VSN@\\\"},\", line); \ print line; \ next; \ } \ /{modules,/ { \ line = \$$0; \ indent = index(line, \"[\"); \ line = substr(line, 1, indent); \ print line; \ split(src, mods); \ mods_count = 0; \ for (mod in mods) { \ mods_count++; \ } \ prefix = sprintf(\"%*s\", indent, \" \"); \ for (i = 1; i <= mods_count; i++) { \ mod = mods[i]; \ sub(/\.erl/, \"\", mod); \ if (i != mods_count) \ print prefix mod \",\"; \ else \ print prefix mod; \ } \ print prefix \"]},\"; \ next; \ } \ { print; }" $< > $@ $(EBIN_DIR)/yapp.appup: @srcdir@/yapp.appup.src $(AM_V_GEN)sed -e "s/%VSN%/@YAPP_VSN@/g" < $< > $@ $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/yapp_sup.erl�������������������������������������������������������0000664�0001750�0001750�00000004474�12605311412�016217� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%------------------------------------------------------------------- %%% File : yapp_sup.erl %%% Author : Mikael Karlsson <mikael@creado.se> %%% Description : %%% %%% Created : 1 Jun 2006 by Mikael Karlsson <mikael@creado.se> %%%------------------------------------------------------------------- -module(yapp_sup). -behaviour(supervisor). %% API -export([start_link/1]). %% Supervisor callbacks -export([init/1]). -define(SERVER, ?MODULE). %%==================================================================== %% API functions %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the supervisor %%-------------------------------------------------------------------- start_link(_) -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). %%==================================================================== %% Supervisor callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Func: init(Args) -> {ok, {SupFlags, [ChildSpec]}} | %% ignore | %% {error, Reason} %% Description: Whenever a supervisor is started using %% supervisor:start_link/[2,3], this function is called by the new process %% to find out about restart strategy, maximum restart frequency and child %% specifications. %%-------------------------------------------------------------------- init([]) -> AllEnv = application:get_all_env(), YappRegistryModule = proplists:get_value(yapp_registry_impl, AllEnv, yapp_mnesia_server), YappRegName = YappRegistryModule, YappRegistry = {yapp_registry_worker,{YappRegistryModule, start_link,[YappRegName]}, permanent,2000,worker,[YappRegistryModule, yapp_registry]}, YappHandler = {yapp_handler_worker,{yapp_server, start_link, [yapp_handler, YappRegName]}, permanent,2000,worker,[yapp_handler, yapp_server]}, {ok,{{one_for_all,0,5}, [YappRegistry, YappHandler]}}. %%==================================================================== %% Internal functions %%==================================================================== ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/yapp.app.src�������������������������������������������������������0000664�0001750�0001750�00000000466�12605311412�016111� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{application, yapp, [{description,"Yaws applications handler"}, {vsn, {cmd, "sed -ne '1,/^YAPP_VSN=/s/^YAPP_VSN=//p' vsn.mk 2>/dev/null"}}, {modules,[]}, {registered, [yapp_handler]}, {mod,{yapp_app,[]}}, {env, [{yapp_registry_impl, yapp_mnesia_server}]}, {applications,[kernel, stdlib, yaws]}]}. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/yapp_handler.erl���������������������������������������������������0000664�0001750�0001750�00000006431�12605311412�017020� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%------------------------------------------------------------------- %%% File : yapp_handler.erl %%% @author Mikael Karlsson <mikael@creado.se> %%% @since 1 Jun 2006 by Mikael Karlsson <mikael@creado.se> %%% @see yapp %%% @see yapp_registry %%% @see yapp_server %%% @doc Yaws applications handler. %%% <p>An easy way to deploy Yaws applications (Yapps) independently of %%% each other. A Yapp is an Erlang application already installed, by for %%% instance erlmerge. %%% </p> %%% <p> %%% To register a Yapp on the virtual server uses the command (example):</p> <code> %%% yapp_handler:add(yapp_handler, "myvirtserverid","/myYappPath", my_app_name) %%% </code> %%% <p>where "myvirtserverid" is the the "server id" set in the opaque variable %%% yapp_server_id in yaws.conf:<pre> %%% &lt;opaque&gt; %%% yapp_server_id = myvirtserverid %%% &lt;/opaque&gt; </pre> %%% </p> %%% <p>If Yaws is running on a different node use: %%% </p><code> %%% yapp_handler:add({yapp_handler,'node@host'}, "myvirtserverid","/myYappPath", my_app_name) %%% </code> %%% <p>The default yapp_handler implementation is yapp_server.</p> %%% <p>The yapp_handler uses the yapp module to change the configuration on Yaws, and the %%% yapp_registry module implementation to store the configuration.</p> -module(yapp_handler). %% API -export([list/2, add/3, add/4, remove/3, init_yapps/1]). %% @spec list(YappServer::pid(), SrvId) -> Yapps | exit() %% SrvID = string() | all %% Yapps = {URL, AppName} | undefined %% URL= string() %% AppName = atom() %% @doc Lists all registered Yapps. list(YappServer, YawsServerId) -> gen_server:call(YappServer,{?MODULE, list, YawsServerId}). %% @spec add(YappServer::pid(), SrvId::string(), YappUrl::string(), AppName::atom()) -> ok | exit() %% @doc Add a Yapp. Adds in the virtual server with the opaque property %% yapp_server_id = SrvID. The YappUrl is the root path to the Yapp and the AppName is %% the Name of the application. add(YappServer, SrvId, YappUrl, AppName) -> gen_server:call(YappServer,{?MODULE, add, {SrvId, YappUrl, AppName}}). %% @spec add(YappServer::pid(), SrvId::string(), AppName::atom()) -> ok | exit() %% @doc Add a Yapp. Adds in the virtual server with the opaque property %% yapp_server_id = SrvID. The root URL will become "/" ++ atom_to_list(AppName) %% the Name of the application. add(YappServer, SrvId, AppName) -> add(YappServer, SrvId, "/" ++ atom_to_list(AppName), AppName). %% @spec remove(YappServer::pid(), SrvId::string(), YappUrlOrName::string()) -> ok | exit() %% YappUrlOrName = string() | atom() %% @doc Remove a Yapp from Yaws. Removes in the virtual server with yapp_server_id = SrvID. %% The YappUrlOrName is either the root path to the Yapp or the name of it. remove(YappServer, SrvId, YappUrlOrName) when is_list(YappUrlOrName)-> gen_server:call(YappServer,{?MODULE, remove, {SrvId, YappUrlOrName}}); remove(YappServer, SrvId, YappUrlOrName) when is_atom(YappUrlOrName)-> remove(YappServer, SrvId, "/" ++ atom_to_list(YappUrlOrName)). %% @spec init_yapps(YappServer::pid()) -> ok | exit() %% @doc Iinitalizes the Yaws Sconfs list with bootstrap_yapps and Yapps in the %% the registry. The default name for YappServer is the atom yapp_handler. init_yapps(YappServer) -> gen_server:call(YappServer,{?MODULE, init_yapps}). ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/yapp_ets_server.erl������������������������������������������������0000664�0001750�0001750�00000006043�12605311412�017563� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%------------------------------------------------------------------- %%% File : yapp_ets_server.erl %%% @author Steve Vinoski <vinoski@ieee.org> %%% @since 17 Apr 2009 by Steve Vinoski <vinoski@ieee.org> %%% @see yapp_registry %%% @doc Yapp registry implementation that uses ets. %%% <p>This module is selected to be used by the yaws handler %%% by setting the application environment property %%% {yapp_registry_impl, yapp_ets_server} in the yapp.app file. %%% It's useful for cases where yapp registration need not be %%% persistent, such as for yapps that are bootstrapped at startup.</p> %%% @end %%%------------------------------------------------------------------- -module(yapp_ets_server). -behavior(gen_server). %% API -export([start_link/1, start/1]). %% implements yapp_registry %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -record(state, { yapps }). start_link(Name) -> gen_server:start_link({local, Name}, ?MODULE, [], []). start(Name) -> gen_server:start({local, Name}, ?MODULE, [], []). %% gen_server callbacks init([]) -> process_flag(trap_exit, true), {ok, #state{ yapps = ets:new(yapps, [private]) }}. handle_call({yapp_registry, list}, _From, State=#state{yapps = Yapps}) -> Reply = ets:foldl(fun(Item, Acc) -> [Item | Acc] end, [], Yapps), {reply, Reply, State}; handle_call({yapp_registry, register, {SrvId, KeyValue={Yappurl, _AppName}}}, _From, State = #state{yapps=Yapps}) -> NewKeyValue = case ets:lookup(Yapps, SrvId) of [] -> [KeyValue]; [{SrvId, UrlApps}] -> case lists:keymember(Yappurl, 1, UrlApps) of false -> [KeyValue | UrlApps]; true -> lists:keyreplace(Yappurl, 1, UrlApps, KeyValue) end end, ets:insert(Yapps, {SrvId, NewKeyValue}), {reply, ok, State}; handle_call({yapp_registry, unregister, {SrvId, Yappurl}}, _From, State = #state{yapps=Yapps}) -> Reply = case ets:lookup(Yapps, SrvId) of [] -> {error, {srv_id_not_defined, SrvId}}; [{SrvId, UrlApps}] -> case lists:keymember(Yappurl, 1, UrlApps) of false -> ok; true -> NKv = lists:keydelete(Yappurl, 1, UrlApps), ets:insert(Yapps, {SrvId, NKv}) end, ok end, {reply, Reply, State}; handle_call(_Request, _From, State) -> {reply, ok, State}. handle_cast(_Msg, State) -> {noreply, State}. handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, #state{yapps = Yapps}) -> ets:delete(Yapps), ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/yapp_server.erl����������������������������������������������������0000664�0001750�0001750�00000013251�12605311412�016707� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%------------------------------------------------------------------- %%% File : yapp_server.erl %%% Author : Mikael Karlsson <mikael@creado.se> %%% Description : %%% %%% Created : 28 May 2006 by Mikael Karlsson <mikael@creado.se> %%%------------------------------------------------------------------- -module(yapp_server). -behaviour(gen_server). %% API -export([start_link/2]). %% implements yapp_handler %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -record(state, {yapp_registry}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Name, YappRegistry) -> gen_server:start_link({local, Name}, ?MODULE, [YappRegistry], []). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([]) -> {ok, #state{}}; init([YappRegistry]) -> self() ! init_yapps, {ok, #state{yapp_registry = YappRegistry}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call({yapp_handler, list, all}, _From, State) -> Reply = yapp_registry:list(State#state.yapp_registry), {reply, Reply, State}; handle_call({yapp_handler, list, SrvId}, _From, State) -> YR = yapp_registry:list(State#state.yapp_registry), Reply = proplists:get_value(SrvId,YR), {reply, Reply, State}; handle_call({yapp_handler, add, {SrvId,YappUrl, AppName}}, _From, State) -> yapp_registry:'register'(State#state.yapp_registry, SrvId,{YappUrl,AppName}), yapp:insert(SrvId, {YappUrl, AppName}), {reply, ok, State}; handle_call({yapp_handler, remove, {SrvId,YappUrl}}, _From, State) -> yapp_registry:'unregister'(State#state.yapp_registry, SrvId, YappUrl), yapp:remove(SrvId, YappUrl), {reply, ok, State}; handle_call({yapp_handler, init_yapps},_From, State) -> Reply = init_yapps(State#state.yapp_registry), {reply, Reply, State}; handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({setdep,{yapp_registry,P}} , State) -> {noreply, State#state{yapp_registry=P}}; handle_info(init_yapps, State) -> init_yapps(State#state.yapp_registry), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- init_yapps(YappRegistry) -> BYS = yapp:get_bootstrap_yapps(), Yapps = yapp_registry:list(YappRegistry), YB = BYS ++ Yapps, case YB of [] -> do_nothing; _ -> yapp:insert(YB) end, Handlers = gen_event:which_handlers(yaws_event_manager), case lists:member(yapp_event_handler, Handlers) of false -> ok = yapp_event_handler:add_handler(yaws_event_manager, yapp_handler); true -> do_nothing end. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/yapp.erl�����������������������������������������������������������0000664�0001750�0001750�00000035764�12605311412�015336� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%% File : yapp.erl %%% @author Mikael Karlsson <mikael@creado.se> %%% @since 11 Dec 2005 by Mikael Karlsson <mikael@creado.se> %%% @see yapp_handler %%% @doc Yaws applications handler. %%% <p>An easy way to deploy Yaws applications independently of %%% each other.</p> %%% <p>This module implements Yaws runmod and arg_rewrite_mod interfaces. %%% It has functions to insert and remove Yapps to the Yaws sconfs records. %%% It is used by the yapp_handler implementation. The yapp module will make Yaws %%% temporarily switch the docroot %%% to the applications priv/docroot directory when it encounters the registered %%% URL path of the application. One can set another docroot than the default %%% (priv/docroot) by setting the environment variable yapp_docroot in the %%% .app file for the application. %%% The application may also have own appmods which are put in the %%% application environment variable yapp_appmods like: </p> %%% <code> {env, [ %%% {yapp_appmods,[{"ctrl",enityme_controller}]} %%% ]}, </code> %%% <p> %%% In order to include the yapp module, runmod shall be set to yapp. %%% The arg_rewrite_mod shall also be set to yapp and the opaque variable %%% yapp_server_id shall be set to an unique string for every virtual server %%% using yapp, like: </p> %%% <pre> %%% . %%% ebin_dir = /usr/local/yaws/lib/yapp/ebin %%% . %%% runmod = yapp %%% . %%% &lt;server aspen4&gt; %%% port = 8001 %%% listen = 0.0.0.0 %%% dir_listings = true %%% arg_rewrite_mod = yapp %%% docroot = /home/yaws/scripts/../www %%% &lt;opaque&gt; %%% yapp_server_id = aspeninternal %%% bootstrap_yapps = yapp %%% &lt;/opaque&gt; %%% &lt;/server&gt; %%% </pre> %%% %%% <p><em>Note:</em> The yapp application is in itself a "Yapp" with a small admin console. %%% So by adding the line <code>bootstrap_yapps = yapp</code> as above you will get access %%% to the admin console on http://yourservername/yapp/index.html</p> %%% <p><em>Note2:</em> The current available registry implementation uses Mnesia so you need %%% to create a mnesia schema (if not already done) for the node(s) you are running Yaws on. %%% <code>mnesia:create_schema([node()]).</code></p> %%% %%% @type yawsArg() = term(). This is the #arg record as defined %%% by yaws_api.hrl. %%% %%% @type yawsSconf() = term(). This is the #sconf record as defined %%% by yaws.hrl. %%% %%% @type yawsGconf() = term(). This is the #gconf record as defined %%% by yaws.hrl. -module(yapp). -author('mikael@creado.se'). -include("yaws_api.hrl"). -export([arg_rewrite/1, start/0, prepath/1, insert/1, insert/2, remove/2, log/3, reset_yaws_conf/0, srv_id/1, get_bootstrap_yapps/0, get_yapps/0, get_server_ids/0]). %% reload_yaws/0, -define(prepath, yapp_prepath). -define(srv_id, "yapp_server_id"). -define(bootstrap_yapps, "bootstrap_yapps"). %% Opaque key for "bootstrap yapps" -define(erlyweb_appname,"appname"). -define(yapp_list, yapp_list). -define(priv_docroot, "priv/docroot"). %% This record is stored in the sconf opaque property yapp_list -record(yapp, { urlpath, docroot = "", appname = "", appmods = [], opaque = [] }). %% The yapp_reg is stored in Mnesia in the y_registry %% and contains a list of {yapp_server_id, yapps} tuples, where %% yapps is a list of {UrlPath, AppName} tuples %% UrlPath = string() %% Interface arg_rewrite_mod %% @spec arg_rewrite(Arg::yawsArg()) -> yawsArg() %% @doc Interface function for a Yaws arg_rewrite_mod. If %% it finds a registered Yapp it will strip of the %% path up to the Yapp and redirect the docroot. arg_rewrite(Arg) -> case find_registered_yapps(Arg) of undefined -> Arg; {#yapp{urlpath = YappPath, docroot = Docroot, appmods = YappMods, opaque = YOpaque }, _Rest} -> DocMount = case string:right(YappPath,1) of "/" -> YappPath; _ -> YappPath ++ "/" end, VDir = {"vdir", DocMount ++ " " ++ Docroot}, AddOpaque = [ VDir | YOpaque], %% Add Yapp appmods, Yaws uses process dictionary. SC = get(sc), AppMods = yaws:sconf_appmods(SC), Opaque = yaws:sconf_opaque(SC), NYappPath = case YappPath of [$/|YPTail] -> YPTail; _ -> YappPath end, RemappedYappMods = lists:map(fun({PE, Mod, Ex}) -> {PE, Mod, [[NYappPath] ++ X || X <- Ex]}; (AM) -> AM end, YappMods), SC2 = yaws:setup_sconf([{docroot, Docroot}, {appmods, AppMods ++ RemappedYappMods}, {opaque, AddOpaque ++ Opaque}], SC), put(sc, SC2), Opaque2 = Arg#arg.opaque, Arg#arg{docroot=Docroot, docroot_mount=DocMount, opaque = AddOpaque ++ Opaque2} end. %% Interface run_mod %% @spec start() -> void() %% @doc Interface function for Yaws run_mod. %% This fun is spawned from Yaws so no return val is expected. %% All Yapps can expect mnesia to be started, so mnesia is ensured %% to be started. %% For every server id that has Yapps the yapp module is registered %% as an arg_rewrite_mod in #sconf. %% Configuration data for mapping Yapp paths to applications is looked %% up in a mnesia registry table and stored in Yaws #sconf.opaque record %% for the each server id. start() -> case wait_for_yaws() of ok -> log(info, "Starting yapp~n",[]), application:start(yapp); Error -> log(error, "Failed waiting for Yaws to start when starting Yapp: ~p~n",[Error]) end. wait_for_yaws() -> wait_for_yaws(20). wait_for_yaws(0) -> {error, timeout}; wait_for_yaws(N) -> WA = application:which_applications(), case lists:keysearch(yaws, 1, WA) of false -> log(info, "Yapp starting but Yaws not ready - waiting 500 ms",[]), receive after 500 -> ok end, %% Give Yaws some time to settle own things wait_for_yaws(N-1); _ -> ok end. %% @spec prepath(Arg::yawsArg()) -> Path::string() %% @doc Get the Yapp root-path. Can be called from a Yapp erl/1 %% fun or an erl section in a .yaws file to get the Yapp root %% path. prepath(Arg) -> Arg#arg.docroot_mount. %% @spec log(Level, FormatStr::string(), Args) -> void() %% Level = error | warning | info | debug %% Args = [term()] %% @doc Yapp interface to the error_logger. log(debug, FormatStr, Args) -> gen_event:notify(error_logger, {debug_msg, group_leader(), {self(), FormatStr, Args}}); log(info, FormatStr, Args) -> error_logger:info_msg(FormatStr, Args); log(warning, FormatStr, Args) -> error_logger:warning_msg(FormatStr, Args); log(error, FormatStr, Args) -> error_logger:error_msg(FormatStr, Args); log(Level, FormatStr, Args) -> error_logger:error_msg("Unknown logging level ~p ," ++ FormatStr,[Level|Args]). %% Utility function find_registered_yapps(Arg) -> Req = Arg#arg.req, {abs_path, Path} = Req#http_request.path, A = proplists:get_value(?yapp_list, Arg#arg.opaque,[]), find_registered(A, Path). find_registered([],_Path) -> undefined; find_registered([ #yapp{urlpath = RegPath} = Y | T ], Path) -> case string:str(Path, RegPath) of 1 -> case string:substr(Path,1+length(RegPath)) of [] -> {Y,[]}; [$/ |_] = Rest -> {Y,Rest}; _ -> find_registered(T,Path) end; _ -> find_registered(T, Path) end. %% @hidden insert([]) -> ok; insert(Yapps) when is_list(Yapps) -> {ok, Gconf, Sconfs} = get_conf(), NewSconfs = (catch insert_yapps_in_sconfs(Yapps, Sconfs)), yaws_api:setconf(Gconf, NewSconfs). %% @hidden insert(SrvId, Yapp)-> {ok, Gconf, SconfGroups} = get_conf(), NewSconfGroups = insert_yapp_in_sconfgroups(SrvId, Yapp, SconfGroups), yaws_api:setconf(Gconf, NewSconfGroups). insert_yapps_in_sconfs([], SconfGroups) -> SconfGroups; insert_yapps_in_sconfs([{_SrvId,[]}|T], SconfGroups) -> insert_yapps_in_sconfs(T, SconfGroups); insert_yapps_in_sconfs([{SrvId,[Y|YS]}|T], SconfGroups) -> NewSconfGroups = insert_yapp_in_sconfgroups(SrvId,Y,SconfGroups), insert_yapps_in_sconfs([{SrvId,YS}|T], NewSconfGroups). insert_yapp_in_sconfgroups(_SrvId, _Yapp,[]) -> []; insert_yapp_in_sconfgroups(SrvId, Yapp, [SCG|T]) -> [insert_yapp_in_sconfgroup(SrvId,Yapp, SCG) | insert_yapp_in_sconfgroups(SrvId,Yapp,T)]. insert_yapp_in_sconfgroup(_SrvId, _Yapp, []) -> []; insert_yapp_in_sconfgroup(SrvId, Yapp, [SC|SCG]) -> case srv_id(SC) of SrvId -> case insert_yapp_in_sconf(Yapp,SC) of no_app -> [SC | SCG]; NewSC -> [NewSC | SCG] end; _ -> [ SC | insert_yapp_in_sconfgroup(SrvId,Yapp,SCG)] end. %% the yapp application itself maybe a yapp, treated as special case insert_yapp_in_sconf({UrlPath, yapp}, SC) -> insert_yapp_in_sconf0({UrlPath, yapp}, SC); insert_yapp_in_sconf({UrlPath, AppName}, SC) -> case start_app([AppName]) of ok -> insert_yapp_in_sconf0({UrlPath, AppName}, SC); Error -> log(error, "yapp:insert_yapp_in_sconf - Error loading Yapp ~p, ~p", [AppName, Error]), no_app end. start_app([AppName|T]) -> log(info, "Starting app ~p" , [AppName]), case application:start(AppName) of {error,{not_started,RequiredApp}} -> start_app([RequiredApp,AppName|T]); {error,{already_started,AppName}} -> start_app(T); ok -> start_app(T); Error -> Error end; start_app([]) -> ok; start_app(Error) -> Error. insert_yapp_in_sconf0({UrlPath, AppName}, SC) -> log(info,"Inserting App ~p in Url ~p~n", [AppName, UrlPath]), OP = yaws:sconf_opaque(SC), AppEnv = application:get_all_env(AppName), DocSubRoot = proplists:get_value(yapp_docroot, AppEnv, ?priv_docroot), YAppMods = proplists:get_value(yapp_appmods, AppEnv, []), YOpaque = proplists:get_value(yapp_opaque, AppEnv, []), Y = #yapp{urlpath= UrlPath, docroot = code:lib_dir(AppName) ++ "/" ++ DocSubRoot, appname = AppName, appmods = YAppMods, opaque = YOpaque }, OP2 = case proplists:get_value(?yapp_list, OP) of undefined -> [{?yapp_list,[Y]} | OP]; YR -> YR2 = insert_yapp_in_yapp_list(Y, YR), lists:keyreplace(?yapp_list, 1, OP, {?yapp_list, YR2}) end, yaws:setup_sconf([{opaque, OP2}], SC). insert_yapp_in_yapp_list(#yapp{} = Y, []) -> [Y]; insert_yapp_in_yapp_list(#yapp{urlpath= UP} = Y, [#yapp{urlpath=UP} | T]) -> [Y|T]; insert_yapp_in_yapp_list(Y, [H | T]) -> [ H | insert_yapp_in_yapp_list(Y,T) ]. %% @hidden remove(SrvId, RegPath) -> {ok, Gconf, Sconfs} = yaws_api:getconf(), NewSconfs = remove_yapp_from_sconfgroups(SrvId, RegPath, Sconfs), yaws_api:setconf(Gconf, NewSconfs). remove_yapp_from_sconfgroups(_SrvId, _RegPath, []) -> []; remove_yapp_from_sconfgroups(SrvId, RegPath, [SCG|T]) -> [remove_yapp_from_sconfgroup(SrvId, RegPath,SCG) | remove_yapp_from_sconfgroups(SrvId, RegPath, T)]. remove_yapp_from_sconfgroup(_SrvId, _RegPath, []) -> []; remove_yapp_from_sconfgroup(SrvId, RegPath, [ H | T ]) -> case srv_id(H) of SrvId -> [ remove_yapp_from_sconf(RegPath, H) | T ]; _ -> [ H | remove_yapp_from_sconfgroup(SrvId, RegPath, T ) ] end. remove_yapp_from_sconf(RegPath, SC) -> OP = yaws:sconf_opaque(SC), OP2 = case proplists:get_value(?yapp_list, OP) of undefined -> OP; YR -> YR2 = remove_yapp_from_yapp_list(RegPath, YR), lists:keyreplace(?yapp_list, 1, OP, {?yapp_list, YR2}) end, yaws:setup_sconf([{opaque, OP2}], SC). remove_yapp_from_yapp_list(_, [] ) -> []; remove_yapp_from_yapp_list(RegPath, [ #yapp{urlpath = RegPath} | T ] ) -> T; remove_yapp_from_yapp_list(RegPath, [H | T]) -> [H | remove_yapp_from_yapp_list(RegPath, T)]. %% by tobbe@tornkvist.org reset_yaws_conf() -> case catch yaws_config:load(yaws_sup:get_app_args()) of {ok, Gconf, Sconfs} -> yaws_api:setconf(Gconf, Sconfs); Err -> Err end. %% @spec get_conf() -> {ok,yawsGconf(), Sconfs} %% Sconfs = [ yawsSconf() ] get_conf() -> yaws_api:getconf(). % yaws_config:load(yaws_sup:get_app_args()). %% @spec srv_id(Sconf) -> string() | undefined %% Sconf = yawsSconf() %% @doc Get the server id from an Sconf if available srv_id(SC) -> OP = yaws:sconf_opaque(SC), proplists:get_value(?srv_id, OP). %% @spec get_bootstrap_yapps() -> [{ ServerId, [ {Path, ApplicationName}]}] %% ServerId = string() %% Path = string() %% Applicationame = atom() %% @doc Gets the Yapps defined in each opaque %% "bootstrap_yapps = appname1, appname2" for every server id. (If available). %% Bootstrap yapps will get the same pathname as their application name %% and are "static" meaning that they can not be removed from the server %% unless yaws.conf is changed (or if embedded yaws - yaws:setconf/2 is used). get_bootstrap_yapps() -> {ok, _Gconf, Sconfs} = get_conf(), YL = [begin OP = yaws:sconf_opaque(SC), {proplists:get_value(?srv_id, OP), make_yapp_tuples(proplists:get_value(?bootstrap_yapps, OP))} end || SC <- lists:flatten(Sconfs) ], [{SrvId, Yapps} || {SrvId, Yapps} <- YL, SrvId =/= undefined, Yapps =/= []]. make_yapp_tuples(undefined) -> []; make_yapp_tuples(BootStrapYapps) -> [ make_yapp_tuple(A) || A <- string:tokens(BootStrapYapps,",")]. make_yapp_tuple(A) -> B = string:strip(A), {"/" ++ B, list_to_atom(B)}. %% @spec get_yapps() -> [{ServId,[{yapp, Urlpath, Docroot, Appname , Appmods}]}] %% Urlpath = string() %% Docroot = string() %% Appname = atom() %% Appmods = [atom()] %% @doc Gets all Yapps that are configured for the Yaws server. get_yapps() -> {ok, _Gconf, Sconfs} = yaws_api:getconf(), Yapps1 = [begin OP = yaws:sconf_opaque(SC), {proplists:get_value("yapp_server_id", OP), proplists:get_value(yapp_list, OP)} end || SC <- lists:flatten(Sconfs)], [{S,Y} || {S,Y} <- Yapps1, Y =/= undefined, S =/= undefined]. %% @spec get_server_ids() -> [string()] %% @doc Lists all server ids. get_server_ids() -> {ok, _Gconf, Sconfs} = get_conf(), SrvIds1 = [begin OP = yaws:sconf_opaque(SC), proplists:get_value("yapp_server_id", OP) end || SC <- lists:flatten(Sconfs)], [S|| S <- SrvIds1, S =/= undefined]. ������������yaws-2.0.2/applications/yapp/src/yapp.appup.src�����������������������������������������������������0000664�0001750�0001750�00000000035�12605311412�016446� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"%VSN%", [ ], [ ]}. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/yapp_registry.erl��������������������������������������������������0000664�0001750�0001750�00000003107�12605311412�017250� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%------------------------------------------------------------------- %%% File : yapp_registry.erl %%% @author Mikael Karlsson <mikael@creado.se> %%% @since 1 June 2006 by Mikael Karlsson <mikael@creado.se> %%% @doc Yapp registry api. %%% <p>The default yapp registry (yapp_mnesia_server) uses mnesia, so a %%% prerequisite is that a schema is created. </p> -module(yapp_registry). %% API -export([list/1, register/3, unregister/3]). %% @spec list(YappRegistry::pid()) -> RegistryContent | exit() %% RegsitryContent = [YawsSrvContent] %% YawsSrvContent = {YawsServerId, Yapps} %% Yapps = [{URL, AppName}] | undefined %% URL= string() %% AppName = atom() %% @doc Lists all registered Yapps. list(YappRegistry) -> gen_server:call(YappRegistry,{?MODULE, list}). %% @spec register(YappRegistry::pid(), SrvId::string(), {YappUrl::string(), AppName::atom()}) -> ok | exit() %% @doc Register a Yapp. Registers in the virtual server with the opaque property %% yapp_server_id = SrvID. The YappUrl is the root path to the Yapp and the AppName is %% the Name of the application. register(YappRegistry, SrvId, {_YappUrl, _AppName} = A) -> gen_server:call(YappRegistry,{?MODULE, register, {SrvId, A}}). %% @spec unregister(YappRegistry::pid(), SrvId::string(), YappUrl::string()) -> ok | exit() %% @doc Unregister a Yapp from Yaws. Unregisters in the virtual server with yapp_server_id = SrvID. %% The YappUrlOrName is either the root path to the Yapp or the name of it. unregister(YappRegistry, SrvId, YappUrl) -> gen_server:call(YappRegistry,{?MODULE, unregister, {SrvId, YappUrl}}). ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/yapp_event_handler.erl���������������������������������������������0000664�0001750�0001750�00000010606�12605311412�020220� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%------------------------------------------------------------------- %%% File : yapp_event_handler.erl %%% @author Mikael Karlsson <mikael@creado.se> %%% @since 3 Jun 2006 by Mikael Karlsson <mikael@creado.se> %%% @see yapp_handler %%% @doc Yapp event handler. %%% <p>Listens for hup events from the Yaws event manager and makes %%% sure that the yapp_handler reinitialise all yapps in case a hup %%% (which resets the Yaws configuration from yaws.conf) occurs. %%% </p> -module(yapp_event_handler). -behaviour(gen_event). %% API -export([add_handler/2]). %% gen_event callbacks -export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3]). -record(state, {yapp_server}). %%-------------------------------------------------------------------- %% Function: add_handler(EventManager, YappServer) -> ok | {'EXIT',Reason} | term() %% Description: Adds an event handler %%-------------------------------------------------------------------- add_handler(EventManager, YappServer) -> gen_event:add_handler(EventManager, ?MODULE, [YappServer]). %%==================================================================== %% gen_event callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} %% Description: Whenever a new event handler is added to an event manager, %% this function is called to initialize the event handler. %%-------------------------------------------------------------------- init([YappServer]) -> {ok, #state{yapp_server = YappServer}}. %%-------------------------------------------------------------------- %% Function: %% handle_event(Event, State) -> {ok, State} | %% {swap_handler, Args1, State1, Mod2, Args2} | %% remove_handler %% Description:Whenever an event manager receives an event sent using %% gen_event:notify/2 or gen_event:sync_notify/2, this function is called for %% each installed event handler to handle the event. %%-------------------------------------------------------------------- handle_event({yaws_hupped, _Res}, State) -> io:format("yapp got hup event~n"), YappServ = State#state.yapp_server, YappServ ! init_yapps, {ok, State}; handle_event(_Event, State) -> {ok, State}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, State) -> {ok, Reply, State} | %% {swap_handler, Reply, Args1, State1, %% Mod2, Args2} | %% {remove_handler, Reply} %% Description: Whenever an event manager receives a request sent using %% gen_event:call/3,4, this function is called for the specified event %% handler to handle the request. %%-------------------------------------------------------------------- handle_call(_Request, State) -> Reply = ok, {ok, Reply, State}. %%-------------------------------------------------------------------- %% Function: %% handle_info(Info, State) -> {ok, State} | %% {swap_handler, Args1, State1, Mod2, Args2} | %% remove_handler %% Description: This function is called for each installed event handler when %% an event manager receives any other message than an event or a synchronous %% request (or a system message). %%-------------------------------------------------------------------- handle_info(_Info, State) -> {ok, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description:Whenever an event handler is deleted from an event manager, %% this function is called. It should be the opposite of Module:init/1 and %% do any necessary cleaning up. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Function: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- ��������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/yapp_app.erl�������������������������������������������������������0000664�0001750�0001750�00000003601�12605311412�016157� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%------------------------------------------------------------------- %%% File : yapp_app.erl %%% Author : Mikael Karlsson <mikael@creado.se> %%% Description : %%% %%% Created : 1 Jun 2006 by Mikael Karlsson <mikael@creado.se> %%%------------------------------------------------------------------- -module(yapp_app). -behaviour(application). %% Application callbacks -export([start/2, stop/1]). %%==================================================================== %% Application callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: start(Type, StartArgs) -> {ok, Pid} | %% {ok, Pid, State} | %% {error, Reason} %% Description: This function is called whenever an application %% is started using application:start/1,2, and should start the processes %% of the application. If the application is structured according to the %% OTP design principles as a supervision tree, this means starting the %% top supervisor of the tree. %%-------------------------------------------------------------------- start(_Type, StartArgs) -> case yapp_sup:start_link(StartArgs) of {ok, Pid} -> {ok, Pid}; Error -> Error end. %%-------------------------------------------------------------------- %% Function: stop(State) -> void() %% Description: This function is called whenever an application %% has stopped. It is intended to be the opposite of Module:start/2 and %% should do any necessary cleaning up. The return value is ignored. %%-------------------------------------------------------------------- stop(_State) -> ok. %%==================================================================== %% Internal functions %%==================================================================== �������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/yapp_mnesia_server.erl���������������������������������������������0000664�0001750�0001750�00000020460�12605311412�020243� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%------------------------------------------------------------------- %%% File : yapp_mnesia_server.erl %%% @author Mikael Karlsson <mikael@creado.se> %%% @since 28 May 2006 by Mikael Karlsson <mikael@creado.se> %%% @see yapp_registry %%% @doc Yapp registry implementation that uses mnesia. %%% <p>This module is selected to be used by the yaws handler %%% by setting the application environment property %%% {yapp_registry_impl, yapp_mnesia_server} in the yapp.app file.</p> %%% @end %%%------------------------------------------------------------------- -module(yapp_mnesia_server). -behaviour(gen_server). %% API -export([start_link/1]). %% implements yapp_registry %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -record(state, {dummy}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Name) -> gen_server:start_link({local, Name}, ?MODULE, [], []). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([]) -> mnesia:start(), mnesia:wait_for_tables([yapp],500), init_y_registry(), %% Create table if necessary init_yapp_reg(), %% Create yapp register if necessary {ok, #state{}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call({yapp_registry, list}, _From, State) -> Reply = list_yapps(), {reply, Reply, State}; handle_call({yapp_registry, register,{SrvId,KeyValue}}, _From, State) -> Reply = register_yapp(SrvId,KeyValue), {reply, Reply, State}; handle_call({yapp_registry, unregister,{SrvId,Key}}, _From, State) -> Reply = unregister_yapp(SrvId,Key), {reply, Reply, State}; handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- %% The yapp_reg is stored in Mnesia in the y_registry %% and contains a list of {yapp_server_id, yapps} tuples, where %% yapps is a list of {UrlPath, AppName} tuples %% UrlPath = string() %% AppName = atom() -record(y_registry, { key, value }). init_y_registry() -> case proplists:get_value(y_registry, mnesia:system_info(tables)) of true -> already_created; _ -> create_y_registry_table() end. create_y_registry_table() -> Opts = [{type,set},{disc_copies, [node()]}], mnesia:create_table(y_registry,[{attributes, record_info(fields,y_registry)} | Opts ]). init_yapp_reg() -> F = fun() -> case get_yapp_reg() of { error, _ } -> put_yapp_reg([]); _ -> do_nothing end end, {atomic, Value} = mnesia:transaction(F), Value. get_yapp_reg() -> case mnesia:read({y_registry, yapp_reg}) of [] -> { error, no_yapp_reg }; [{y_registry,yapp_reg,YappReg}] -> YappReg end. put_yapp_reg(YappReg) -> mnesia:write(#y_registry{ key=yapp_reg, value=YappReg}). list_yapps() -> {atomic, Value} = mnesia:transaction(fun() -> get_yapp_reg() end), Value. %% @spec register_yapp(SrvId::string(), {YappUrl::string(), AppName::atom()}) -> ok | exit() %% @doc Register a Yapp. Registers in the virtual server with the opaque property %% yapp_server_id = SrvID. The YappUrl is the root path to the Yapp and the AppName is %% the Name of the application. register_yapp(SrvId, KeyValue) -> {atomic, Value} = mnesia:transaction(fun() -> register2(SrvId,KeyValue) end), Value. register2(SrvId, {YappUrl, AppName}) -> YR = get_yapp_reg(), YR2 = case proplists:get_value(SrvId,YR) of undefined -> [{SrvId,[{YappUrl,AppName}]} | YR ]; UrlApps -> UrlApps2 = insert_into_urlapps(YappUrl,AppName,UrlApps), lists:keyreplace(SrvId, 1, YR, {SrvId,UrlApps2}) end, put_yapp_reg(YR2). %% @spec unregister_yapp(SrvId::string(), YappUrl::string()) -> ok | exit() %% @doc Unregister a Yapp. Unregisters in the virtual server with yapp_server_id = SrvID. %% The YappUrl is the root path to the Yapp. unregister_yapp(SrvId, YappUrl) -> {atomic, Value} = mnesia:transaction(fun() -> unregister2(SrvId,YappUrl) end), Value. unregister2(SrvId,YappUrl) -> YR = get_yapp_reg(), case proplists:get_value(SrvId,YR) of undefined -> {error, {srv_id_not_defined, SrvId}}; UrlApps -> YR2 = case delete_from_urlapps(YappUrl, UrlApps) of [] -> lists:keydelete(SrvId,1,YR); UrlApps2 -> lists:keyreplace(SrvId, 1, YR, {SrvId,UrlApps2}) end, put_yapp_reg(YR2) end. insert_into_urlapps(YappUrl,AppName,UrlApps)-> case lists:keymember(YappUrl, 1, UrlApps) of false -> [{YappUrl,AppName}|UrlApps]; true -> lists:keyreplace(YappUrl, 1, UrlApps, {YappUrl, AppName}) end. delete_from_urlapps(YappUrl, UrlApps) -> case lists:keymember(YappUrl, 1, UrlApps) of false -> UrlApps; true -> lists:keydelete(YappUrl, 1, UrlApps) end. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/src/Makefile.am��������������������������������������������������������0000664�0001750�0001750�00000003424�12605311412�015701� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include @top_srcdir@/include.mk MODULES = yapp_app.erl \ yapp.erl \ yapp_ets_server.erl \ yapp_event_handler.erl\ yapp_handler.erl \ yapp_mnesia_server.erl\ yapp_registry.erl \ yapp_server.erl \ yapp_sup.erl EXTRA_DIST = $(MODULES) yapp.app.src yapp.appup.src EBIN_DIR=@builddir@/../ebin EBIN_FILES=$(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_DIR)/yapp.app $(EBIN_DIR)/yapp.appup $(EBIN_FILES) clean-local: $(AM_V_at)rm -f $(EBIN_DIR)/yapp.app $(EBIN_DIR)/yapp.appup $(EBIN_FILES) $(EBIN_DIR)/yapp.app: @srcdir@/yapp.app.src $(AM_V_GEN)$(AWK) -v src="$(MODULES)" \ "/{vsn, *{cmd,/ { \ line = \$$0; \ sub(/{vsn.*/, \"{vsn, \\\"@YAPP_VSN@\\\"},\", line); \ print line; \ next; \ } \ /{modules,/ { \ line = \$$0; \ indent = index(line, \"[\"); \ line = substr(line, 1, indent); \ print line; \ split(src, mods); \ mods_count = 0; \ for (mod in mods) { \ mods_count++; \ } \ prefix = sprintf(\"%*s\", indent, \" \"); \ for (i = 1; i <= mods_count; i++) { \ mod = mods[i]; \ sub(/\.erl/, \"\", mod); \ if (i != mods_count) \ print prefix mod \",\"; \ else \ print prefix mod; \ } \ print prefix \"]},\"; \ next; \ } \ { print; }" $< > $@ $(EBIN_DIR)/yapp.appup: @srcdir@/yapp.appup.src $(AM_V_GEN)sed -e "s/%VSN%/@YAPP_VSN@/g" < $< > $@ $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/examples/��������������������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�014751� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/examples/README��������������������������������������������������������0000664�0001750�0001750�00000001236�12605311412�015553� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Modify yaws.conf as: %% add path to yapp and yapp example - modify to your own installation directory ebin_dir = $(prefix)/lib/yapp/ebin ebin_dir = $(prefix)/lib/yapp/examples/yapp_ex_1/ebin %% add yapp runmod runmod = yapp %% add to first <server ...> arg_rewrite_mod = yapp <opaque> yapp_server_id = external </opaque> %% add to second <server ..>, that is to <server localhost> %% note you will only be able to access the yapp admin interface from http://localhost[:port]/yapp/ arg_rewrite_mod = yapp <opaque> yapp_server_id = internal bootstrap_yapps = yapp </opaque> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/examples/yapp_ex_1/����������������������������������������������������0000775�0001750�0001750�00000000000�12605311412�016636� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/examples/yapp_ex_1/priv/�����������������������������������������������0000775�0001750�0001750�00000000000�12605311412�017616� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/examples/yapp_ex_1/priv/docroot/���������������������������������������0000775�0001750�0001750�00000000000�12605311412�021267� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/examples/yapp_ex_1/priv/docroot/index.yaws�����������������������������0000664�0001750�0001750�00000002566�12605311412�023234� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <head><title>Yapp example 1 - simple</title></head> <body> <h3>Yapp simple example</h3> <p>Yaws applications is built on the OTP application concept, but this does not mean they need to be complex. In the simplest form an OTP applications is made of a .app description file and the necessary library files. There is no need to have application modules (application_app.erl), supervisors, gen_servers etc. unless they are really needed. </p> <p>This application is a very simple example and contains only two files:</p> <pre> yapp_ex_1/ebin/yapp_ex_1.app - otp .app file yapp_ex_1/priv/docroot/index.yaws - yaws file </pre> <p>The index.yaws file contains this text and the script part:</p> <pre> out(A) -&gt; Header = "Cache-Control:no-store", [X] = string:tokens(yapp:prepath(A),"/"), [{header, Header}, {ehtml, [{p,[], X ++ " there"}]}]. </pre> <p>Which gives URL path to that dispatches to the application appended with "there":</p> <erl> out(A) -> Header = "Cache-Control:no-store", [X] = string:tokens(yapp:prepath(A),"/"), [{header, Header}, {ehtml, [{p,[], X ++ " there"}]}]. </erl> <p>The default text will be "yapp_ex_1 there" but if you register your yapp under another path, e.g. "hi" will get another outcome. Note that you can register your yapp under several virtual hosts and use different dispatch paths.</p> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/examples/yapp_ex_1/ebin/�����������������������������������������������0000775�0001750�0001750�00000000000�12605311412�017553� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/examples/yapp_ex_1/ebin/yapp_ex_1.app����������������������������������0000664�0001750�0001750�00000000252�12605311412�022061� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{application, yapp_ex_1, [{description,"Simple yaws application"}, {vsn,"1.0.0"}, {modules,[]}, {registered, []}, {applications,[kernel, stdlib, yaws, yapp]}]}. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/vsn.mk�����������������������������������������������������������������0000664�0001750�0001750�00000000017�12605311412�014210� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������YAPP_VSN=0.4.2 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/applications/yapp/Makefile.am������������������������������������������������������������0000664�0001750�0001750�00000002224�12605311412�015107� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������SUBDIRS = src ebin EDOC_OPTS=[{def,{vsn,"@YAPP_VSN@"}}, {source_path, ["@srcdir@"]}, {packages, false}] EXTRA_DIST = vsn.mk README priv examples install-data-local: docs $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp) $(AM_V_at)(cd @srcdir@; tar cf - priv examples ) | (cd $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp); tar xf - ) $(AM_V_at)(cd @builddir@; tar cf - doc ) | (cd $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp); tar xf - ) $(AM_V_at)if test $(yappdir) != $(ERLANG_INSTALL_LIB_DIR_yapp); then \ $(INSTALL) -d $(DESTDIR)$(libdir); \ rm -f $(DESTDIR)$(libdir)/yapp; \ $(LN_S) -f $(ERLANG_INSTALL_LIB_DIR_yapp) $(DESTDIR)$(libdir)/yapp; \ fi uninstall-local: $(AM_V_at)rm -fr $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp)/doc $(AM_V_at)rm -fr $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp)/priv $(AM_V_at)rm -fr $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yapp)/examples $(AM_V_at)[ ! -h $(yappdir) ] || rm -f $(DESTDIR)$(libdir)/yapp docs: $(AM_V_at)$(MKDIR_P) doc $(AM_V_at)$(ERL) -noshell -run edoc_run application "'yapp'" '"."' '$(EDOC_OPTS)' -s init stop clean-local: $(AM_V_at)rm -rf doc # Local Variables: # tab-width: 8 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/known_dialyzer_warnings������������������������������������������������������������������0000664�0001750�0001750�00000002562�12605311412�014313� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ yaws.erl:1576: The pattern 'false' can never match the type [[any()]] yaws.erl:2642: Guard test Ret::'file' == 'fd' can never succeed yaws.erl:2650: Guard test Ret::'file' == 'binfd' can never succeed yaws_api.erl:2603: The pattern 'false' can never match the type 'true' yaws_config.erl:603: The pattern 'false' can never match the type 'true' yaws_config.erl:1914: The variable _ can never match since previous clauses completely covered the type 'true' yaws_config.erl:1934: The variable _ can never match since previous clauses completely covered the type 'true' yaws_config.erl:3232: The pattern 'false' can never match the type 'true' yaws_ctl.erl:533: Function hup/1 has no local return yaws_ctl.erl:538: Function stop/1 has no local return yaws_ctl.erl:542: Function status/1 has no local return yaws_ctl.erl:545: Function load/1 has no local return yaws_ctl.erl:567: Function trace/1 has no local return yaws_ctl.erl:570: Function debug_dump/1 has no local return yaws_ctl.erl:573: Function stats/1 has no local return yaws_ctl.erl:575: Function running_config/1 has no local return yaws_revproxy.erl:677: The pattern 'true' can never match the type 'false' yaws_sendfile.erl:51: The pattern 'false' can never match the type 'true' yaws_sendfile.erl:62: The pattern 'false' can never match the type 'true' yaws_sup_restarts.erl:49: The pattern 'false' can never match the type 'true' ����������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/configure.ac�����������������������������������������������������������������������������0000664�0001750�0001750�00000053634�12605311412�011715� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl ------------------------------------------------------------------ dnl Autoconf initialization. dnl ------------------------------------------------------------------ m4_define([VERSION_NUMBER], m4_esyscmd([. ./vsn.mk && printf '%s' ${YAWS_VSN}])) AC_INIT([yaws], VERSION_NUMBER) AC_CONFIG_SRCDIR([src/yaws_app.erl]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([ac-aux]) dnl work out who the cpu, vendor and OS are AC_CANONICAL_SYSTEM AC_DEFINE_UNQUOTED(CPU_VENDOR_OS, "$host") AM_INIT_AUTOMAKE([1.11 -Wall -Wno-portability foreign]) AC_PREREQ([2.64]) ECHO=echo COLORED_ECHO_INIT dnl ------------------------------------------------------------------ dnl Compiler and other tools. dnl ------------------------------------------------------------------ old_cflags="$CFLAGS" AM_SILENT_RULES([yes]) m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) dnl AC_PREFIX_DEFAULT(/usr) AC_PROG_CC AC_PROG_GCC_TRADITIONAL AC_PROG_LD AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_SED AM_DISABLE_STATIC AM_ENABLE_SHARED AM_PROG_LIBTOOL CFLAGS="-Werror -Wall -O3 $old_cflags" dnl ------------------------------------------------------------------ dnl Handle configure options. dnl ------------------------------------------------------------------ AC_ARG_WITH([defaultcharset], AC_HELP_STRING([--with-defaultcharset=CHARSET], [specify default charset, i.e UTF-8]), with_defaultcharset=${withval%/}, with_defaultcharset="") if test "x${with_defaultcharset}" = "x"; then DEFAULT_CHARSET=undefined else DEFAULT_CHARSET="\"${with_defaultcharset}\"" fi AC_SUBST(DEFAULT_CHARSET) AC_ARG_WITH([extrainclude], AS_HELP_STRING([--with-extrainclude=DIR], [dir to include if e.g. pam is installed in some odd place]), with_extrainclude=${withval%/}, with_extrainclude="") if test "x$with_extrainclude" = "x" ; then EXTRAINCLUDE= else EXTRAINCLUDE=-I${with_extrainclude} fi AC_SUBST(EXTRAINCLUDE) AC_ARG_ENABLE([pam], AC_HELP_STRING([--disable-pam], [disable pam auth]), enable_pam="$enableval", enable_pam="yes") AM_CONDITIONAL(WITH_EPAM, [test "x${enable_pam}" = "xyes"]) APPDEPS= AC_ARG_ENABLE(crypto, AS_HELP_STRING([--enable-crypto], [adds crypto application to yaws.app file])) if test "x$enable_crypto" = "xyes"; then APPDEPS=',crypto' fi AC_ARG_ENABLE(compiler, AS_HELP_STRING([--enable-compiler], [adds compiler application to yaws.app file])) if test "x$enable_compiler" = "xyes"; then APPDEPS="${APPDEPS},compiler" fi AC_SUBST(APPDEPS) dnl ------------------------------------------------------------------ dnl Erlang environment. dnl ------------------------------------------------------------------ echo COLORED_ECHO([%BCheck Erlang environment & applications%b]) tmp_cross_compiling=$cross_compiling cross_compiling=no dnl Available flags. AC_ARG_WITH([erlang], AC_HELP_STRING([--with-erlang=PREFIX], [prefix where Erlang is installed (optional)]), with_erlang=${withval%/}, with_erlang="") dnl erl(1) is used to compile Erlang modules. if test "x${with_erlang}" = "x"; then AC_ERLANG_PATH_ERL AC_ERLANG_PATH_ERLC else erl_path="${with_erlang}/bin" AC_ERLANG_PATH_ERL(, [$erl_path$PATH_SEPARATOR$PATH]) AC_ERLANG_PATH_ERLC(, [$erl_path$PATH_SEPARATOR$PATH]) fi if test "x${ERL}" = "x"; then AC_MSG_ERROR([ Erlang not found. Fill the ERL variable with erl(1) path or provide Erlang prefix with --with-erlang.]) fi dnl escript(1) is used by the testsuite. AC_ARG_VAR([ESCRIPT], [Erlang/OTP interpreter command [autodetected]]) if test "x${ESCRIPT}" = "x"; then if test "x${with_erlang}" = "x"; then AC_PATH_PROG([ESCRIPT], [escript],,) else erl_path="${with_erlang}/bin" AC_PATH_PROG([ESCRIPT], [escript],, [$erl_path$PATH_SEPARATOR$PATH]) fi else AC_MSG_CHECKING([for escript]) AC_MSG_RESULT([$ESCRIPT]) fi if test "x${ESCRIPT}" = "x"; then AC_MSG_WARN([ escript(1) not found. Fill the ESCRIPT variable with escript(1) path if you want to use the testsuite.]) fi dnl dialyzer(1). AC_ARG_VAR([DIALYZER], [Erlang/OTP discrepancy analyzer [autodetected]]) if test "x${DIALYZER}" = "x"; then if test "x${with_erlang}" = "x"; then AC_PATH_PROG([DIALYZER], [dialyzer],,) else erl_path="${with_erlang}/bin" AC_PATH_PROG([DIALYZER], [dialyzer],, [$erl_path$PATH_SEPARATOR$PATH]) fi else AC_MSG_CHECKING([for dialyzer]) AC_MSG_RESULT([$DIALYZER]) fi if test "x${DIALYZER}" = "x"; then AC_MSG_WARN([ dialyzer(1) not found. Fill the DIALYZER variable with dialyzer(1) path if you want to use it.]) fi dnl Declare ERL_LIBS as precious. AC_ARG_VAR([ERL_LIBS], [Erlang/OTP applications search path [none]]) dnl Get Erlang $ROOT dir and lib dir. AC_ERLANG_SUBST_ROOT_DIR AC_ERLANG_SUBST_LIB_DIR dnl Get ERTS version. ERLANG_CHECK_ERTS ERLANG_CHECK_RELEASE dnl Require Erlang >=R14B02 (ERTS 5.8.3) is required. AX_COMPARE_VERSION([${ERLANG_ERTS_VER}], [ge], [5.8.3], [], [AC_MSG_ERROR([Erlang R14B02 or higher is required but only Erlang $ERLANG_RELEASE was found!])]) dnl Unicode module was buggy for R14B04 and previous (ERTS <= 5.8.5) AC_MSG_CHECKING([for buggy unicode module]) AX_COMPARE_VERSION([${ERLANG_ERTS_VER}], [le], [5.8.5], [bad_unicode="yes"], [bad_unicode="no"]) AC_MSG_RESULT([${bad_unicode}]) HAVE_BAD_UNICODE=false if test "x${bad_unicode}" = "xyes"; then HAVE_BAD_UNICODE=true fi AM_CONDITIONAL(HAVE_BAD_UNICODE, [test "x$HAVE_BAD_UNICODE" = "xtrue"]) AC_SUBST(HAVE_BAD_UNICODE) dnl filelib:wildcard/2 was buggy for R15B03 and previous (ERTS <= 5.9.3) AC_MSG_CHECKING([for buggy filelib:wildcard/2 function]) AX_COMPARE_VERSION([${ERLANG_ERTS_VER}], [le], [5.9.3], [bad_wildcard="yes"], [bad_wildcard="no"]) AC_MSG_RESULT([${bad_wildcard}]) HAVE_BAD_WILDCARD=false if test "x${bad_wildcard}" = "xyes"; then HAVE_BAD_WILDCARD=true fi AM_CONDITIONAL(HAVE_BAD_WILDCARD, [test "x$HAVE_BAD_WILDCARD" = "xtrue"]) AC_SUBST(HAVE_BAD_WILDCARD) dnl Check for support of honor_cipher_order SSL option (ERTS >= 6.0) AC_MSG_CHECKING([for support of honor_cipher_order SSL option]) AX_COMPARE_VERSION([${ERLANG_ERTS_VER}], [ge], [6.0], [ssl_honor_cipher_order="yes"], [ssl_honor_cipher_order="no"]) AC_MSG_RESULT([${ssl_honor_cipher_order}]) HAVE_SSL_HONOR_CIPHER_ORDER=false if test "x${ssl_honor_cipher_order}" = "xyes"; then HAVE_SSL_HONOR_CIPHER_ORDER=true fi AM_CONDITIONAL(HAVE_SSL_HONOR_CIPHER_ORDER, [test "x$HAVE_SSL_HONOR_CIPHER_ORDER" = "xtrue"]) AC_SUBST(HAVE_SSL_HONOR_CIPHER_ORDER) dnl Check for support of client_renegotiation SSL option (ERTS >= 7.0) AC_MSG_CHECKING([for support of client_renegotiation SSL option]) AX_COMPARE_VERSION([${ERLANG_ERTS_VER}], [ge], [7.0], [ssl_client_renegotiation="yes"], [ssl_client_renegotiation="no"]) AC_MSG_RESULT([${ssl_client_renegotiation}]) HAVE_SSL_CLIENT_RENEGOTIATION=false if test "x${ssl_client_renegotiation}" = "xyes"; then HAVE_SSL_CLIENT_RENEGOTIATION=true fi AM_CONDITIONAL(HAVE_SSL_CLIENT_RENEGOTIATION, [test "x$HAVE_SSL_CLIENT_RENEGOTIATION" = "xtrue"]) AC_SUBST(HAVE_SSL_CLIENT_RENEGOTIATION) dnl Check for support of log_alert SSL option (ERTS >= 5.10.3) AC_MSG_CHECKING([for support of log_alert SSL option]) AX_COMPARE_VERSION([${ERLANG_ERTS_VER}], [ge], [5.10.3], [ssl_log_alert="yes"], [ssl_log_alert="no"]) AC_MSG_RESULT([${ssl_log_alert}]) HAVE_SSL_LOG_ALERT=false if test "x${ssl_log_alert}" = "xyes"; then HAVE_SSL_LOG_ALERT=true fi AM_CONDITIONAL(HAVE_SSL_LOG_ALERT, [test "x$HAVE_SSL_LOG_ALERT" = "xtrue"]) AC_SUBST(HAVE_SSL_LOG_ALERT) dnl Determine directories for installation. if test "x${prefix}" != "xNONE" -a "x${ERLANG_INSTALL_LIB_DIR}" = "x"; then dnl Under $prefix ERLANG_INSTALL_LIB_DIR='${prefix}/lib' else dnl Under default erlang libdir ERLANG_INSTALL_LIB_DIR='${ERLANG_LIB_DIR}' fi AC_ERLANG_SUBST_INSTALL_LIB_DIR . ${srcdir}/vsn.mk AC_SUBST(YAWS_VSN) AC_ERLANG_SUBST_INSTALL_LIB_SUBDIR(AC_PACKAGE_NAME, ${YAWS_VSN}) . ${srcdir}/applications/yapp/vsn.mk AC_SUBST(YAPP_VSN) AC_ERLANG_SUBST_INSTALL_LIB_SUBDIR(yapp, ${YAPP_VSN}) dnl ------------------------------------------------------------------ dnl Erlang applicatons. dnl ------------------------------------------------------------------ AC_ERLANG_CHECK_LIB([kernel],, [AC_MSG_ERROR(["kernel" Erlang application not found.])]) AC_ERLANG_CHECK_LIB([stdlib],, [AC_MSG_ERROR(["stdlib" Erlang application not found.])]) AC_ERLANG_CHECK_LIB([sasl],, [AC_MSG_ERROR(["compiler" Erlang application not found.])]) AC_ERLANG_CHECK_LIB([erts],, [AC_MSG_ERROR(["compiler" Erlang application not found.])]) AC_ERLANG_CHECK_LIB([compiler],, [AC_MSG_ERROR(["compiler" Erlang application not found.])]) AC_ERLANG_CHECK_LIB([crypto],, [AC_MSG_ERROR(["crypto" Erlang application not found.])]) AC_ERLANG_CHECK_LIB([xmerl],, [AC_MSG_ERROR(["xmerl" Erlang application not found.])]) AC_ERLANG_CHECK_LIB([public_key],,[AC_MSG_WARN(["public_key" Erlang application not found. It could be required to run Yaws or its testsuites.])]) AC_ERLANG_CHECK_LIB([ssl],, [AC_MSG_WARN(["ssl" Erlang application not found. It could be required to run Yaws or its testsuites.])]) AC_ERLANG_CHECK_LIB([mnesia],, [AC_MSG_WARN(["mnesia" Erlang application not found. It could be required to run Yaws or its testsuites.])]) AC_ERLANG_CHECK_LIB([eunit],, [AC_MSG_WARN(["eunit" Erlang application not found. It could be required to run Yaws or its testsuites.])]) AC_ERLANG_CHECK_LIB([erlsom],, [AC_MSG_WARN(["erlsom" Erlang application not found. It could be required to run Yaws or its testsuites.])]) AC_ERLANG_CHECK_LIB([xmlrpc],, [AC_MSG_WARN(["xmlrpc" Erlang application not found. It could be required to run Yaws or its testsuites.])]) AC_ERLANG_CHECK_LIB([inets],, [AC_MSG_WARN(["xmlrpc" Erlang application not found. It could be required to run Yaws or its testsuites.])]) cross_compiling=$tmp_cross_compiling dnl ------------------------------------------------------------------ dnl Check platform-specific stuff dnl ------------------------------------------------------------------ echo COLORED_ECHO([%BCheck platform-specific and system requirements%b]) AC_MSG_CHECKING([for the build and host architectures]) case "$host_os" in *cygwin*) AC_MSG_RESULT([windows (native)]) CYGWIN=true AC_PATH_PROG(WERL, werl) AC_SUBST(WERL) ;; mingw|mingw32*) AC_MSG_RESULT([windows (cross-compiled)]) MINGW=true AC_PATH_PROG(WERL, werl) AC_SUBST(WERL) ;; *) AC_MSG_RESULT([$host_os]) dnl Sigh, pam headers do not seem to have a standard place. On FreeBSD and dnl Linuces I've seen they are in /usr/include/security, but MacOS has them dnl in /usr/include/pam. EPAM_CFLAGS= if test "x$enable_pam" != "xno"; then AC_CHECK_HEADERS([security/pam_appl.h pam/pam_appl.h pam_appl.h],[break]) if test "x$ac_cv_header_security_pam_appl_h" = "xyes" ; then EPAM_CFLAGS="-I/usr/include/security" elif test "x$ac_cv_header_pam_pam_appl_h" = "xyes" ; then EPAM_CFLAGS="-I/usr/include/pam" elif test "x$ac_cv_header_pam_appl_h" = "xno" ; then AC_MSG_ERROR("Could not find pam_appl.h required for pam authentication") fi AC_CHECK_LIB(pam,pam_start,[],[AC_MSG_ERROR("Could not find pam library")]) fi AC_SUBST(EPAM_CFLAGS) ;; esac AM_CONDITIONAL(CYGWIN, [test "x$CYGWIN" = "xtrue"]) AM_CONDITIONAL(MINGW, [test "x$MINGW" = "xtrue"]) AM_CONDITIONAL(WINDOWS, [test "x$MINGW" = "xtrue" -o "x$CYGWIN" = "xtrue"]) dnl check sendfile support: dnl - HAVE_SENDFILE: say if sendfile syscall is supported dnl - HAVE_ERLANG_SENDFILE: say if file:sendfile/5 exists HAVE_SENDFILE=false HAVE_ERLANG_SENDFILE=false dnl Disabled because the yaws driver is not compiled for windows if test "$WINDOWS" = true; then AC_MSG_CHECKING([for sendfile]) AC_MSG_RESULT([no]) else AC_LANG(C) AC_CHECK_LIB([c],[sendfile],[HAVE_SENDFILE=true]) fi AC_MSG_CHECKING([for file:sendfile/5]) file_sendfile=`"${ERL}" -noshell -eval 'code:ensure_loaded(file), io:format("~p~n",[[erlang:function_exported(file,sendfile,5)]]), erlang:halt().' | tail -1` if test "$file_sendfile" = true; then AX_COMPARE_VERSION([${ERLANG_ERTS_VER}], [ge], [5.9.1], [AC_MSG_RESULT([yes]) HAVE_ERLANG_SENDFILE=true], [AC_MSG_RESULT([no])]) else AC_MSG_RESULT([no]) fi AM_CONDITIONAL(HAVE_SENDFILE, [test "x$HAVE_SENDFILE" = "xtrue"]) AM_CONDITIONAL(HAVE_ERLANG_SENDFILE, [test "x$HAVE_ERLANG_SENDFILE" = "xtrue"]) AC_SUBST(HAVE_SENDFILE) AC_SUBST(HAVE_ERLANG_SENDFILE) AC_MSG_CHECKING([for crypto:hash/2]) HAVE_CRYPTO_HASH=false crypto_hash=`"${ERL}" -noshell -eval 'code:ensure_loaded(crypto), io:format("~p~n",[[erlang:function_exported(crypto,hash,2)]]), erlang:halt().' | tail -1` if test "$crypto_hash" = true; then HAVE_CRYPTO_HASH=true AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi AM_CONDITIONAL(HAVE_CRYPTO_HASH, [test "x$HAVE_CRYPTO_HASH" = "xtrue"]) AC_SUBST(HAVE_CRYPTO_HASH) AC_MSG_CHECKING([for inet:parse_strict_address/1]) HAVE_INET_PARSE_STRICT_ADDRESS=false inet_parse_strict_address=`"${ERL}" -noshell -eval 'code:ensure_loaded(inet), io:format("~p~n",[[erlang:function_exported(inet, parse_strict_address,1)]]), erlang:halt().' | tail -1` if test "$inet_parse_strict_address" = true; then HAVE_INET_PARSE_STRICT_ADDRESS=true AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi AM_CONDITIONAL(HAVE_INET_PARSE_STRICT_ADDRESS, [test "x$INET_PARSE_STRICT_ADDRESS" = "xtrue"]) AC_SUBST(HAVE_INET_PARSE_STRICT_ADDRESS) dnl erlang:now/0 is deprecated in erts 7.0 and newer AC_MSG_CHECKING([for erlang:now/0]) AX_COMPARE_VERSION([${ERLANG_ERTS_VER}], [lt], [7.0], [have_erlang_now="yes"], [have_erlang_now="no"]) AC_MSG_RESULT([${have_erlang_now}]) HAVE_ERLANG_NOW=false if test "x${have_erlang_now}" = "xyes"; then HAVE_ERLANG_NOW=true fi AM_CONDITIONAL(HAVE_ERLANG_NOW, [test "x$HAVE_ERLANG_NOW" = "xtrue"]) AC_SUBST(HAVE_ERLANG_NOW) dnl ------------------------------------------------------------------ dnl Check for programs used during Yaws compilation/installation dnl ------------------------------------------------------------------ echo COLORED_ECHO([%BCheck programs support%b]) dnl Make LaTeX and related commands configurable dnl dnl We might want to check whether latex is pdflatex and creates PDF instead of dnl DVI without being given -output-format=dvi. However, this at least allows dnl to give the working command at configure time. AC_ARG_VAR([DVILATEX], [(pdf)latex command creating DVI file]) AC_CHECK_PROG([DVILATEX], [latex], [latex]) AC_ARG_VAR([DVIPS], [dvips command]) AC_CHECK_PROG([DVIPS], [dvips], [dvips]) AC_ARG_VAR([PDFLATEX], [(pdf)latex command creating PDF file]) AC_CHECK_PROG([PDFLATEX], [pdflatex], [pdflatex]) AC_ARG_VAR([EPSTOPDF], [epstopdf command]) AC_CHECK_PROG([EPSTOPDF], [epstopdf], [epstopdf]) AC_ARG_VAR([MAN], [man command creating manpages]) AC_CHECK_PROG([MAN], [man], [man]) AC_ARG_VAR([PS2PDF], [ps2pdf command creating PDF file]) AC_CHECK_PROG([PS2PDF], [ps2pdf], [ps2pdf]) AM_CONDITIONAL(CAN_BUILD_DOC, [test "x$DVILATEX" != "x" && test "x$DVIPS" != "x" && test "x$PDFLATEX" != "x" && test "x$EPSTOPDF" != "x"]) AC_ARG_VAR([CADAVER], [command-line WebDAV client for Unix]) AC_CHECK_PROG([CADAVER], [cadaver], [cadaver]) AC_ARG_VAR([CURL], [command-line tool for transferring data with URL syntax]) AC_CHECK_PROG([CURL], [curl], [curl]) AC_ARG_VAR([UNIX2DOS], [converts DOS <-> Unix text files]) AC_CHECK_PROG([UNIX2DOS], [unix2dos], [unix2dos]) AC_ARG_VAR([TODOS], [converts DOS <-> Unix text files]) AC_CHECK_PROG([TODOS], [todos], [todos]) AC_ARG_VAR([INSTALL_BUILDER], [BitRock InstallBuilder directory ['${HOME}/installbuilder-5.4.14']]) if test "x${INSTALL_BUILDER}" = "x"; then INSTALL_BUILDER="${HOME}/installbuilder-5.4.14" fi dnl ------------------------------------------------------------------ dnl Final path substitutions dnl ------------------------------------------------------------------ AC_ARG_VAR([confdir], [Default Yaws configuration directory ['$(sysconfdir)/yaws']]) if test "x${confdir}" = "x"; then confdir='$(sysconfdir)/yaws' fi AC_ARG_VAR([wwwdir], [Default Yaws docroot ['$(localstatedir)/yaws/www']]) if test "x${wwwdir}" = "x"; then wwwdir='$(localstatedir)/yaws/www' fi AC_ARG_VAR([appsdir], [Default Yaws applications directory ['$(localstatedir)/yaws']]) if test "x${appsdir}" = "x"; then appsdir='$(localstatedir)/yaws' fi AC_ARG_VAR([logdir], [Default Yaws log directory ['$(localstatedir)/log/yaws']]) if test "x${logdir}" = "x"; then logdir='$(localstatedir)/log/yaws' fi AC_ARG_VAR([yawsdir], [Default Yaws installation directory ['$(libdir)/yaws']. If not specified, it is a link on '$(ERLANG_INSTALL_LIB_DIR_yaws)']) if test "x${yawsdir}" = "x"; then yawsdir='$(libdir)/yaws' else dnl If yawsdir is defined, replace ERLANG_INSTALL_LIB_DIR_yaws too ERLANG_INSTALL_LIB_DIR_yaws='${yawsdir}' fi AC_ARG_VAR([yappdir], [Default Yapp installation directory ['$(libdir)/yapp']. If not specified, it is a link on '$(ERLANG_INSTALL_LIB_DIR_yapp)']) if test "x${yappdir}" = "x"; then yappdir='$(libdir)/yapp' else dnl If yappdir is defined, replace ERLANG_INSTALL_LIB_DIR_yapp too ERLANG_INSTALL_LIB_DIR_yapp='${yappdir}' fi dnl ------------------------------------------------------------------ dnl Autoconf output. dnl ------------------------------------------------------------------ AC_SUBST([CONFIG_STATUS_DEPENDENCIES], ['$(top_srcdir)/vsn.mk $(top_srcdir)/applications/yapp/vsn.mk']) AC_CONFIG_FILES([ yaws.pc Makefile c_src/Makefile win32/Makefile win32/build.xml man/Makefile doc/Makefile scripts/Makefile src/Makefile ebin/Makefile examples/src/Makefile examples/ebin/Makefile examples/include/Makefile www/code/Makefile www/shoppingcart/Makefile test/Makefile test/src/Makefile test/eunit/Makefile test/t1/Makefile test/t2/Makefile test/t3/Makefile test/t4/Makefile test/t5/Makefile test/t6/Makefile test/t7/Makefile test/t8/Makefile test/t9/Makefile test/t10/Makefile test/t11/Makefile test/t12/Makefile test/t13/Makefile test/t14/Makefile applications/chat/Makefile applications/chat/src/Makefile applications/chat/ebin/Makefile applications/mail/Makefile applications/mail/src/Makefile applications/mail/ebin/Makefile applications/wiki/Makefile applications/wiki/src/Makefile applications/wiki/ebin/Makefile applications/yapp/Makefile applications/yapp/src/Makefile applications/yapp/ebin/Makefile src/yaws_charset.hrl src/yaws_appdeps.hrl test/eunit//subconfig_DATA/yaws_absolute.conf test/eunit//subconfig_DATA/yaws_absolute_no_wildcard.conf test/eunit//subconfig_DATA/global_absolute_subconfig.conf test/eunit//subconfig_DATA/global_absolute_no_wildcard_subconfig.conf test/support/yaws.conf test/t1/yaws.conf test/t2/yaws.conf test/t3/yaws.conf test/t4/yaws.conf test/t5/yaws.conf test/t6/no_docroot_appmod.conf test/t6/no_docroot_fwdproxy.conf test/t6/no_docroot_redirect.conf test/t6/no_docroot_revproxy.conf test/t7/yaws.conf test/t8/yaws.conf test/t9/yaws.conf test/t10/yaws.conf test/t11/yaws.conf test/t12/yaws.conf test/t13/yaws.conf test/t14/yaws.conf ]) AC_CONFIG_FILES([scripts/make-release], [chmod +x scripts/make-release]) AC_CONFIG_FILES([applications/wiki/scripts/addFile], [chmod +x applications/wiki/scripts/addFile]) AC_CONFIG_FILES([applications/wiki/scripts/getPassword], [chmod +x applications/wiki/scripts/getPassword]) AC_CONFIG_FILES([applications/wiki/scripts/importFiles], [chmod +x applications/wiki/scripts/importFiles]) AC_CONFIG_FILES([applications/wiki/scripts/updateWiki], [chmod +x applications/wiki/scripts/updateWiki]) dnl when srcdir != builddir, we need to create some symlinks AC_CONFIG_FILES([include/Makefile], [ AS_IF([test -e include/yaws.hrl], [], [ln -s ${ac_abs_srcdir}/yaws.hrl include/yaws.hrl]) AS_IF([test -e include/yaws_api.hrl], [], [ln -s ${ac_abs_srcdir}/yaws_api.hrl include/yaws_api.hrl]) ]) AC_CONFIG_FILES([priv/Makefile], [ AS_IF([test -e priv/mime.types], [], [ln -s ${ac_abs_srcdir}/mime.types priv/mime.types]) ]) AC_OUTPUT dnl -------------------------------------------------- dnl Configuration report dnl -------------------------------------------------- echo COLORED_ECHO([ %B== ${PACKAGE_NAME} ${PACKAGE_VERSION} ==%b]) echo COLORED_ECHO([Configuration:]) COLORED_ECHO([ %BApplication dir.%b: ${ERLANG_INSTALL_LIB_DIR_yaws}]) echo COLORED_ECHO([ %BPrefix%b: ${prefix}]) COLORED_ECHO([ %Betcdir%b: ${sysconfdir}]) COLORED_ECHO([ %Bconfdir%b: ${confdir}]) COLORED_ECHO([ %Bbindir%b: ${bindir}]) COLORED_ECHO([ %Bvardir%b: ${localstatedir}]) COLORED_ECHO([ %Bwwwdir%b: ${wwwdir}]) COLORED_ECHO([ %Bappsdir%b: ${appsdir}]) COLORED_ECHO([ %Blogdir%b: ${logdir}]) COLORED_ECHO([ %Byawsdir%b: ${yawsdir}]) COLORED_ECHO([ %Bdocdir%b: ${docdir}]) COLORED_ECHO([ %Bmandir%b: ${mandir}]) echo COLORED_ECHO([ %BErlang root dir%b: ${ERLANG_ROOT_DIR}]) COLORED_ECHO([ %BErlang lib dir%b: ${ERLANG_LIB_DIR}]) COLORED_ECHO([ %BErlang compiler%b: ${ERLC}]) COLORED_ECHO([ %BErlang emulator%b: ${ERL}]) COLORED_ECHO([ %BWindows Erlang emulator%b: ${WERL}]) echo ����������������������������������������������������������������������������������������������������yaws-2.0.2/examples/��������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312014�011311� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/include/������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312014�012734� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/include/Makefile.in�������������������������������������������������������������0000664�0001750�0001750�00000041540�12605311446�014735� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = examples/include DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(dist_inc_DATA) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(incdir)" DATA = $(dist_inc_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ incdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/examples/include dist_inc_DATA = all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign examples/include/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_incDATA: $(dist_inc_DATA) @$(NORMAL_INSTALL) @list='$(dist_inc_DATA)'; test -n "$(incdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(incdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(incdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(incdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(incdir)" || exit $$?; \ done uninstall-dist_incDATA: @$(NORMAL_UNINSTALL) @list='$(dist_inc_DATA)'; test -n "$(incdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(incdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(incdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-dist_incDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_incDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dist_incDATA install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am uninstall-dist_incDATA # Add custom install target because there is no header to install install-data-local: $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yaws)/examples/include # Local Variables: # tab-width: 8 # End: # 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: ����������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/include/Makefile.am�������������������������������������������������������������0000664�0001750�0001750�00000000440�12605311412�014707� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������incdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/examples/include dist_inc_DATA = # Add custom install target because there is no header to install install-data-local: $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_yaws)/examples/include # Local Variables: # tab-width: 8 # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/ebin/���������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312014�012226� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/ebin/Makefile.in����������������������������������������������������������������0000664�0001750�0001750�00000041265�12605311445�014232� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = examples/ebin DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(beamdir)" DATA = $(beam_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ beamdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/examples/ebin BEAM_FILES = *.beam beam_DATA = $(BEAM_FILES) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/ebin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign examples/ebin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-beamDATA: $(beam_DATA) @$(NORMAL_INSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(beamdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(beamdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(beamdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(beamdir)" || exit $$?; \ done uninstall-beamDATA: @$(NORMAL_UNINSTALL) @list='$(beam_DATA)'; test -n "$(beamdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(beamdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(beamdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-beamDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-beamDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-beamDATA install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-beamDATA clean-local: $(AM_V_at)rm -f $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: # 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: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/ebin/Makefile.am����������������������������������������������������������������0000664�0001750�0001750�00000000302�12605311412�014176� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������beamdir = $(ERLANG_INSTALL_LIB_DIR_yaws)/examples/ebin BEAM_FILES = *.beam beam_DATA = $(BEAM_FILES) clean-local: $(AM_V_at)rm -f $(BEAM_FILES) # Local Variables: # tab-width: 8 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/src/����������������������������������������������������������������������������0000775�0001750�0001750�00000000000�12605312014�012100� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/src/Makefile.in�����������������������������������������������������������������0000664�0001750�0001750�00000036034�12605311446�014103� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ 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@ target_triplet = @target@ subdir = examples/src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/colored-echo.m4 $(top_srcdir)/m4/erlang.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPDEPS = @APPDEPS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CADAVER = @CADAVER@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURL = @CURL@ CYGPATH_W = @CYGPATH_W@ DEFAULT_CHARSET = @DEFAULT_CHARSET@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIALYZER = @DIALYZER@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DVILATEX = @DVILATEX@ DVIPS = @DVIPS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EPAM_CFLAGS = @EPAM_CFLAGS@ EPSTOPDF = @EPSTOPDF@ ERL = @ERL@ ERLANG_ERTS_DIR = @ERLANG_ERTS_DIR@ ERLANG_ERTS_VER = @ERLANG_ERTS_VER@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_yapp = @ERLANG_INSTALL_LIB_DIR_yapp@ ERLANG_INSTALL_LIB_DIR_yaws = @ERLANG_INSTALL_LIB_DIR_yaws@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLANG_LIB_DIR_compiler = @ERLANG_LIB_DIR_compiler@ ERLANG_LIB_DIR_crypto = @ERLANG_LIB_DIR_crypto@ ERLANG_LIB_DIR_erlsom = @ERLANG_LIB_DIR_erlsom@ ERLANG_LIB_DIR_erts = @ERLANG_LIB_DIR_erts@ ERLANG_LIB_DIR_eunit = @ERLANG_LIB_DIR_eunit@ ERLANG_LIB_DIR_inets = @ERLANG_LIB_DIR_inets@ ERLANG_LIB_DIR_kernel = @ERLANG_LIB_DIR_kernel@ ERLANG_LIB_DIR_mnesia = @ERLANG_LIB_DIR_mnesia@ ERLANG_LIB_DIR_public_key = @ERLANG_LIB_DIR_public_key@ ERLANG_LIB_DIR_sasl = @ERLANG_LIB_DIR_sasl@ ERLANG_LIB_DIR_ssl = @ERLANG_LIB_DIR_ssl@ ERLANG_LIB_DIR_stdlib = @ERLANG_LIB_DIR_stdlib@ ERLANG_LIB_DIR_xmerl = @ERLANG_LIB_DIR_xmerl@ ERLANG_LIB_DIR_xmlrpc = @ERLANG_LIB_DIR_xmlrpc@ ERLANG_LIB_VER_compiler = @ERLANG_LIB_VER_compiler@ ERLANG_LIB_VER_crypto = @ERLANG_LIB_VER_crypto@ ERLANG_LIB_VER_erlsom = @ERLANG_LIB_VER_erlsom@ ERLANG_LIB_VER_erts = @ERLANG_LIB_VER_erts@ ERLANG_LIB_VER_eunit = @ERLANG_LIB_VER_eunit@ ERLANG_LIB_VER_inets = @ERLANG_LIB_VER_inets@ ERLANG_LIB_VER_kernel = @ERLANG_LIB_VER_kernel@ ERLANG_LIB_VER_mnesia = @ERLANG_LIB_VER_mnesia@ ERLANG_LIB_VER_public_key = @ERLANG_LIB_VER_public_key@ ERLANG_LIB_VER_sasl = @ERLANG_LIB_VER_sasl@ ERLANG_LIB_VER_ssl = @ERLANG_LIB_VER_ssl@ ERLANG_LIB_VER_stdlib = @ERLANG_LIB_VER_stdlib@ ERLANG_LIB_VER_xmerl = @ERLANG_LIB_VER_xmerl@ ERLANG_LIB_VER_xmlrpc = @ERLANG_LIB_VER_xmlrpc@ ERLANG_RELEASE = @ERLANG_RELEASE@ ERLANG_ROOT_DIR = @ERLANG_ROOT_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ERL_LIBS = @ERL_LIBS@ ESCRIPT = @ESCRIPT@ EXEEXT = @EXEEXT@ EXTRAINCLUDE = @EXTRAINCLUDE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_BAD_UNICODE = @HAVE_BAD_UNICODE@ HAVE_BAD_WILDCARD = @HAVE_BAD_WILDCARD@ HAVE_CRYPTO_HASH = @HAVE_CRYPTO_HASH@ HAVE_ERLANG_NOW = @HAVE_ERLANG_NOW@ HAVE_ERLANG_SENDFILE = @HAVE_ERLANG_SENDFILE@ HAVE_INET_PARSE_STRICT_ADDRESS = @HAVE_INET_PARSE_STRICT_ADDRESS@ HAVE_SENDFILE = @HAVE_SENDFILE@ HAVE_SSL_CLIENT_RENEGOTIATION = @HAVE_SSL_CLIENT_RENEGOTIATION@ HAVE_SSL_HONOR_CIPHER_ORDER = @HAVE_SSL_HONOR_CIPHER_ORDER@ HAVE_SSL_LOG_ALERT = @HAVE_SSL_LOG_ALERT@ INSTALL = @INSTALL@ INSTALL_BUILDER = @INSTALL_BUILDER@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAN = @MAN@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TODOS = @TODOS@ UNIX2DOS = @UNIX2DOS@ VERSION = @VERSION@ WERL = @WERL@ YAPP_VSN = @YAPP_VSN@ YAWS_VSN = @YAWS_VSN@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appsdir = @appsdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ 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@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ wwwdir = @wwwdir@ yappdir = @yappdir@ yawsdir = @yawsdir@ MODULES = advanced_echo_callback.erl \ authmod_gssapi.erl \ basic_echo_callback.erl \ basic_echo_callback_extended.erl \ server_sent_events.erl EXTRA_DIST = $(MODULES) EBIN_DIR = @builddir@/../ebin EBIN_FILES = $(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign examples/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am include @top_srcdir@/include.mk include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: # 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: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/src/advanced_echo_callback.erl��������������������������������������������������0000664�0001750�0001750�00000012546�12605311412�017114� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%============================================================== %%% compiled using erlc -I include src/advanced_echo_callback.erl %%%============================================================== -module(advanced_echo_callback). -export([handle_message/2]). -include("yaws_api.hrl"). %% define callback state to accumulate a fragmented WS message %% which we echo back when all fragments are in, returning to %% initial state. -record(state, {frag_type = none, % fragment type acc = <<>>}). % accumulate fragment data %% unfragmented text message handle_message(#ws_frame_info{fin=1, opcode=text, data=Data}, #state{frag_type=none, acc = <<>>}=State) -> case unicode:characters_to_binary(Data, utf8, utf8) of Data -> {reply, {text, Data}, State}; _ -> {close, {1007, <<"invalid utf-8">>}} end; %% start of a fragmented text message handle_message(#ws_frame_info{fin=0, opcode=text, data=Data}, #state{frag_type=none, acc = <<>>}) -> case unicode:characters_to_binary(Data, utf8, utf8) of Data -> {noreply, #state{frag_type=text, acc={[Data], <<>>}}}; {incomplete, Dec, Rest} -> {noreply, #state{frag_type=text, acc={[Dec], Rest}}}; _ -> {close, {1007, <<"invalid utf-8">>}} end; %% non-final continuation of a fragmented text message handle_message(#ws_frame_info{fin=0, data=Data, opcode=continuation}, #state{frag_type=text, acc={Dec0, Rest0}}=State) -> Data1 = <<Rest0/binary, Data/binary>>, case unicode:characters_to_binary(Data1, utf8, utf8) of Data1 -> {noreply, State#state{acc={[Data1|Dec0], <<>>}}}; {incomplete, Dec1, Rest1} -> {noreply, State#state{acc={[Dec1|Dec0], Rest1}}}; _ -> {close, {1007, <<"invalid utf-8">>}} end; %% end of text fragmented message handle_message(#ws_frame_info{fin=1, opcode=continuation, data=Data}, #state{frag_type=text, acc={Dec, Rest}}) -> Data1 = <<Rest/binary, Data/binary>>, case unicode:characters_to_binary(Data1, utf8, utf8) of Data1 -> Msg = list_to_binary(lists:reverse([Data1|Dec])), {reply, {text, Msg}, #state{}}; _ -> {close, {1007, <<"invalid utf-8">>}} end; %% unfragmented binary message handle_message(#ws_frame_info{fin=1, opcode=binary, data=Data}, #state{frag_type=none, acc = <<>>}=State) -> {reply, {binary, Data}, State}; %% start of a fragmented binary message handle_message(#ws_frame_info{fin=0, opcode=binary, data=Data}, #state{frag_type=none, acc = <<>>}) -> {noreply, #state{frag_type=binary, acc=Data}}; %% non-final continuation of a fragmented binary message handle_message(#ws_frame_info{fin=0, data=Data, opcode=continuation}, #state{frag_type=binary, acc=FragAcc}=State) -> {noreply, State#state{acc = <<FragAcc/binary,Data/binary>>}}; %% end of binary fragmented message handle_message(#ws_frame_info{fin=1, opcode=continuation, data=Data}, #state{frag_type=binary, acc=FragAcc}) -> Unfragged = <<FragAcc/binary, Data/binary>>, {reply, {binary, Unfragged}, #state{}}; handle_message(#ws_frame_info{opcode=ping, data=Data}, State) -> io:format("replying pong to ping~n",[]), {reply, {pong, Data}, State}; handle_message(#ws_frame_info{opcode=pong}, State) -> %% A response to an unsolicited pong frame is not expected. %% http://tools.ietf.org/html/\ %% draft-ietf-hybi-thewebsocketprotocol-08#section-4 io:format("ignoring unsolicited pong~n",[]), {noreply, State}; %% According to RFC 6455 section 5.4, control messages like close %% MAY be injected in the middle of a fragmented message, which is %% why we pass FragType and FragAcc along below. Whether any clients %% actually do this in practice, I don't know. handle_message(#ws_frame_info{opcode=close, length=Len, data=Data, ws_state=WSState}, _State) -> Reason = case Len of 0 -> {1000, <<>>}; 1 -> {1002, <<"protocol error">>}; _ -> <<Status:16/big, Msg/binary>> = Data, case unicode:characters_to_binary(Msg, utf8, utf8) of Msg -> {check_close_code(Status, WSState), Msg}; _ -> {1007, <<"invalid utf-8">>} end end, io:format("got close. reply reason: ~p~n", [Reason]), {close, Reason}; handle_message(#ws_frame_info{}=FrameInfo, State) -> io:format("WS Endpoint Unhandled message: ~p~n~p~n", [FrameInfo, State]), {close, {1002, <<"protocol error">>}}; handle_message({fail_connection, Status, Msg}, State) -> io:format("Connection failure: ~p:~p~n~p~n", [Status, Msg, State]), {close, {Status, Msg}}. %% The checks for close status codes here are based on RFC 6455 and on the %% autobahn testsuite (http://autobahn.ws/testsuite). check_close_code(Code, WSState) -> if Code >= 3000 andalso Code =< 4999 -> Code; Code < 1000 -> 1002; Code == 1006 andalso WSState#ws_state.sock == undefined -> Code; Code >= 1004 andalso Code =< 1006 -> 1002; Code > 1011 -> 1002; true -> Code end. ����������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/src/basic_echo_callback.erl�����������������������������������������������������0000664�0001750�0001750�00000002141�12605311412�016416� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%=========================================================== %%% compiled using erlc -I include src/basic_echo_callback.erl %%%=========================================================== -module(basic_echo_callback). %% Export for websocket callbacks -export([handle_message/1]). %% Export for apply -export([say_hi/1]). handle_message({text, <<"bye">>}) -> io:format("User said bye.~n", []), {close, normal}; handle_message({text, <<"something">>}) -> io:format("Some action without a reply~n", []), noreply; handle_message({text, <<"say hi later">>}) -> io:format("saying hi in 3s.~n", []), timer:apply_after(3000, ?MODULE, say_hi, [self()]), {reply, {text, <<"I'll say hi in a bit...">>}}; handle_message({text, Message}) -> io:format("basic echo handler got ~p~n", [Message]), {reply, {text, <<Message/binary>>}}; handle_message({binary, Message}) -> {reply, {binary, Message}}; handle_message({close, Status, _Reason}) -> {close, Status}. say_hi(Pid) -> io:format("asynchronous greeting~n", []), yaws_api:websocket_send(Pid, {text, <<"hi there!">>}). �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/src/basic_echo_callback_extended.erl��������������������������������������������0000664�0001750�0001750�00000005537�12605311412�020312� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%=========================================================== %%% compiled using erlc -I include src/basic_echo_callback.erl %%%=========================================================== -module(basic_echo_callback_extended). -include("yaws_api.hrl"). %% Export for websocket callbacks -export([init/1, terminate/2, handle_open/2, handle_message/2, handle_info/2]). %% Export for apply -export([say_hi/1]). -record(state, {nb_texts=0, nb_bins=0}). init([_Arg, Params]) -> io:format("Initalize ~p: ~p~n", [self(), Params]), {ok, #state{}}. handle_open(WSState, State) -> yaws_websockets:send(WSState, {text, <<"Welcome !">>}), {ok, State}. handle_message({text, <<"bye">>}, #state{nb_texts=N, nb_bins=M}=State) -> io:format("User said bye. ~p text / ~p binary messages echoed ~n", [N, M]), NbTexts = list_to_binary(integer_to_list(N)), NbBins = list_to_binary(integer_to_list(M)), Messages = [ {text, <<"Goodbye !">>}, {text, <<NbTexts/binary, " text messages echoed">>}, {text, <<NbBins/binary, " binary messages echoed">>} ], {close, {1000, <<"bye">>}, Messages, State}; handle_message({text, <<"something">>}, State) -> io:format("Some action without a reply~n", []), {noreply, State}; handle_message({text, <<"say hi later">>}, State) -> timer:apply_after(3000, ?MODULE, say_hi, [self()]), {noreply, State}; handle_message({text, <<"fragmented message">>}, State) -> io:format("Send a message fragmented in 3 frames~n", []), Frag1 = #ws_frame{fin = false, opcode = text, payload = <<"frag1">>}, Frag2 = #ws_frame{fin = false, opcode = continuation, payload = <<"frag2">>}, Frag3 = #ws_frame{fin = true, opcode = continuation, payload = <<"frag3">>}, {reply, [Frag1, Frag2, Frag3], State}; handle_message({text, Msg}, #state{nb_texts=N}=State) -> io:format("Receive text message (N=~p): ~p bytes~n", [N, byte_size(Msg)]), {reply, {text, Msg}, State#state{nb_texts=N+1}}; handle_message({binary, Msg}, #state{nb_bins=M}=State) -> io:format("Receive binary message (M=~p): ~p bytes~n", [M, byte_size(Msg)]), {reply, {binary, Msg}, State#state{nb_bins=M+1}}; handle_message({close, Status, Reason}, _) -> io:format("Close connection: ~p - ~p~n", [Status, Reason]), {close, Status}. handle_info(timeout, State) -> io:format("process timed out~n", []), {reply, {text, <<"Anybody Else ?">>}, State}; handle_info(_Info, State) -> {noreply, State}. terminate(Reason, State) -> io:format("terminate ~p: ~p (state:~p)~n", [self(), Reason, State]), ok. say_hi(Pid) -> io:format("asynchronous greeting~n", []), yaws_api:websocket_send(Pid, {text, <<"hi there!">>}). �����������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/examples/src/authmod_gssapi.erl����������������������������������������������������������0000664�0001750�0001750�00000012777�12605311412�015552� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%------------------------------------------------------------------- %%% File : authmod_gssapi.erl %%% Author : Mikael Magnusson <mikael@skinner.hem.za.org> %%% Description : Negotiate authentication module supporting GSSAPI %%% and SPNEGO %%% %%% Created : 17 May 2007 by Mikael Magnusson <mikael@skinner.hem.za.org> %%%------------------------------------------------------------------- %%% %%% Copyright (c) 2007 Mikael Magnusson %%% All rights reserved. %%% %%% Redistribution and use in source and binary forms, with or without %%% modification, are permitted provided that the following conditions %%% are met: %%% %%% 1. Redistributions of source code must retain the above copyright %%% notice, this list of conditions and the following disclaimer. %%% %%% 2. Redistributions in binary form must reproduce the above copyright %%% notice, this list of conditions and the following disclaimer in the %%% documentation and/or other materials provided with the distribution. %%% %%% 3. Neither the name of the copyright owner nor the names of its %%% contributors may be used to endorse or promote products derived from %%% this software without specific prior written permission. %%% %%% THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND %%% ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE %%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE %%% ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE %%% FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL %%% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS %%% OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) %%% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT %%% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY %%% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF %%% SUCH DAMAGE. %% this code adds support for SPNEGO and GSSAPI negotiation to yaws. %% It's compatible with both Linux/Unix and Windows. %% Supporting both Kerberos for windows (kfw) and SSPI on Windows. %% It's implemented as an authmod called authmod_gssapi. %% Adding it to start_mod in <server> and authmod in an <auth> tag %% activates the module. It expects a Kerberos keytab in <opaque>. %% The keytab should contain key(s) for "HTTP/<fqdn>@<REALM>", %% where <fqdn> is the fully qualified domain name of the host and <REALM> %% the kerberos realm. %% For example: %% <server fqdn> %% port = 80 %% listen = 0.0.0.0 %% docroot = /usr/share/yaws %% start_mod = authmod_gssapi %% <auth> authmod = authmod_gssapi %% dir = / %% </auth> %% <opaque> %% keytab = /etc/yaws/http.keytab %% </opaque> %% </server> %% The authmod_gssapi module depends on egssapi %% from: http://www.hem.za.org/egssapi/ -module(authmod_gssapi). -export([ start/1, stop/0, auth/2, get_header/0, out/1 ]). -include("yaws_api.hrl"). -define(SERVER, ?MODULE). -define(SUPERVISOR, yaws_sup). %%-define(ENABLE_DEBUG, yes). -ifdef(ENABLE_DEBUG). -define(INFO, io:format). -define(DEBUG, io:format). -else. -define(INFO, ignore). -define(DEBUG, ignore). -endif. -define(WARNING, io:format). -define(ERROR, io:format). start(Sconf) when is_tuple(Sconf), element(1, Sconf) == sconf -> Opaque = yaws:sconf_opaque(Sconf), start_opaque(Opaque); start(Keytab) when is_list(Keytab) -> ChildSpec = {?SERVER, {egssapi, start_link, [{local, ?SERVER}, Keytab]}, permanent, 1000, worker, [egssapi, spnego]}, supervisor:start_child(?SUPERVISOR, ChildSpec). stop() -> egssapi:stop(?SERVER), supervisor:terminate_child(?SUPERVISOR, ?SERVER), supervisor:delete_child(?SUPERVISOR, ?SERVER). out(Arg) -> yaws_outmod:out(Arg). auth(Arg, _Auth) -> H = Arg#arg.headers, ?INFO("~p~n", [?MODULE]), case H#headers.authorization of {_, _, "Negotiate " ++ Data} -> ?INFO("Negotiate~n", []), Bin = base64:decode(Data), case catch spnego:accept_sec_context(?SERVER, Bin) of {'EXIT', Reason} -> ?ERROR("spnego failed EXIT:~p~n", [Reason]), throw(Reason); {error, Reason} -> ?ERROR("spnego failed error:~p~n", [Reason]), throw(Reason); {ok, {Context, User, Ccname, Resp}} -> ?DEBUG("spnego user ok ~p~n", [User]), spnego:delete_sec_context(Context), {true, {User, Ccname, base64:encode(Resp)}}; E -> ?ERROR("spnego error ~p~n", [E]), throw(error) end; _ -> ?INFO("Request auth~n"), {appmod, ?MODULE} end. %% The header that is set when authentication fails get_header() -> yaws:make_www_authenticate_header("Negotiate"). start_opaque(Opaque) when is_list(Opaque) -> if is_list(Opaque) -> Keytab = get_option("keytab", Opaque), start(Keytab); true -> throw(keytab_not_found) end. get_option(Name, Options) when is_list(Options) -> case lists:keysearch(Name, 1, Options) of {value, {Name, Value}} -> Value; false -> throw(not_found) end. -ifndef(ENABLE_DEBUG). ignore(_) -> ok. ignore(_,_) -> ok. -endif. �yaws-2.0.2/examples/src/server_sent_events.erl������������������������������������������������������0000664�0001750�0001750�00000004765�12605311412�016464� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������%%%---------------------------------------------------------------------- %%% File : server_sent_events.erl %%% Author : Steve Vinoski <vinoski@ieee.org> %%% Purpose : Server-Sent Events example %%% Created : 1 June 2012 by Steve Vinoski <vinoski@ieee.org> %%%---------------------------------------------------------------------- -module(server_sent_events). -behaviour(gen_server). -include("yaws_api.hrl"). %% API -export([out/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -record(state, { sock, yaws_pid, timer }). out(A) -> case (A#arg.req)#http_request.method of 'GET' -> case yaws_api:get_header(A#arg.headers, accept) of undefined -> {status, 406}; Accept -> case string:str(Accept, "text/event-stream") of 0 -> {status, 406}; _ -> {ok, Pid} = gen_server:start(?MODULE, [A], []), yaws_sse:headers(Pid) end end; _ -> [{status, 405}, {header, {"Allow", "GET"}}] end. init([Arg]) -> process_flag(trap_exit, true), {ok, #state{sock=Arg#arg.clisock}}. handle_call(_Request, _From, State) -> {reply, ok, State}. handle_cast(_Msg, State) -> {noreply, State}. handle_info({ok, YawsPid}, State) -> {ok, Timer} = timer:send_interval(1000, self(), tick), {noreply, State#state{yaws_pid=YawsPid, timer=Timer}}; handle_info({discard, _YawsPid}, State) -> %% nothing to do {stop, normal, State}; handle_info(tick, #state{sock=Socket}=State) -> Time = erlang:localtime(), Data = yaws_sse:data(httpd_util:rfc1123_date(Time)), case yaws_sse:send_events(Socket, Data) of ok -> {noreply, State}; {error, closed} -> {stop, normal, State}; {error, Reason} -> {stop, Reason, State} end; handle_info({tcp_closed, _}, State) -> {stop, normal, State#state{sock=closed}}; handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, #state{sock=Socket, yaws_pid=YawsPid, timer=Timer}) -> case Timer of undefined -> ok; _ -> timer:cancel(Timer) end, yaws_api:stream_process_end(Socket, YawsPid), ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. �����������yaws-2.0.2/examples/src/Makefile.am�����������������������������������������������������������������0000664�0001750�0001750�00000001223�12605311412�014053� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include @top_srcdir@/include.mk MODULES = advanced_echo_callback.erl \ authmod_gssapi.erl \ basic_echo_callback.erl \ basic_echo_callback_extended.erl \ server_sent_events.erl EXTRA_DIST = $(MODULES) EBIN_DIR=@builddir@/../ebin EBIN_FILES=$(MODULES:%.erl=$(EBIN_DIR)/%.beam) ERLC_FLAGS = $(ERLC_GENERIC_FLAGS) include @top_srcdir@/erlang_deps.mk all-local: $(EBIN_FILES) $(EBIN_DIR)/%.beam: %.erl $(AM_V_at)$(ERLC) $(ERLC_FLAGS) -M -MF $(@:$(EBIN_DIR)/%.beam=$(DEPDIR)/%.Pbeam) -MT $@ $< $(AM_V_ERLC)$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< distclean-local: $(AM_V_at)rm -fr $(DEPDIR) # Local Variables: # tab-width: 8 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/README.osx�������������������������������������������������������������������������������0000664�0001750�0001750�00000000623�12605311412�011105� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Homebrew on OSX If you develop on OS X (Mavericks, Mountain Lion, Lion, Snow Leopard), the Yaws formula works correctly for users of Erlang/OTP R16B01 and above. To install please run: brew install yaws To install the HEAD using Homebrew run: brew install --HEAD yaws This capability was made to work correctly with [this pull request merge](https://github.com/mxcl/homebrew/pull/23076). �������������������������������������������������������������������������������������������������������������yaws-2.0.2/two-mode-mode.el�������������������������������������������������������������������������0000664�0001750�0001750�00000011254�12605311413�012417� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������;; two-mode-mode.el -- switches between tcl and sgml(html) modes ;; $Id$ ;; Copyright 1999-2004 The Apache Software Foundation ;; Licensed under the Apache License, Version 2.0 (the "License"); ;; you may not use this file except in compliance with the License. ;; You may obtain a copy of the License at ;; http://www.apache.org/licenses/LICENSE-2.0 ;; Unless required by applicable law or agreed to in writing, software ;; distributed under the License is distributed on an "AS IS" BASIS, ;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ;; See the License for the specific language governing permissions and ;; limitations under the License. ;; These same concepts could be used to do a number of neat 2-mode ;; modes, for things like PHP, or anything else where you have a ;; couple of modes you'd like to use. ;; Use of 'psgml-mode' is highly recommended. It is, of course, a ;; part of Debian GNU/Linux. ;; Author: David N. Welton <davidw@dedasys.com> ;; Modified by Marco Pantaleoni <panta@elasticworld.org> ;; to allow execution of an hook on mode switching. ;; Also added a standard mode hook and some documentation strings. ;; Janko Heilgeist <janko@heilgeist.com> and Stefan Schimanski ;; <1stein@gmx.de> submitted modifications that enable the use of ;; multiple modes, so I suppose that 'two-mode-mode' isn't strictly ;; accurate anymore. ;; Modified May 2010 by Steve Vinoski to work with emacs 23. ;; configure these: (defvar default-mode (list "SGML" 'sgml-mode)) (defvar second-modes (list (list "Erlang" "<erl>" "</erl>" 'erlang-mode) (list "Erlang" "<?erl" "?>" 'erlang-mode) (list "C++" "<?php" "?>" 'c++-mode) (list "Python" "<?python" "?>" 'python-mode) (list "Tcl" "<?" "?>" 'tcl-mode) )) ;; ---------------- (defvar two-mode-update nil) (defvar two-mode-mode-idle-timer nil) (defvar two-mode-bool nil) (defvar two-mode-mode-delay (/ (float 1) (float 8))) ;; Two mode hook (defvar two-mode-hook nil "*Hook called by `two-mode'.") (setq two-mode-hook nil) ;; Mode switching hook (defvar two-mode-switch-hook nil "*Hook called upon mode switching.") (setq two-mode-switch-hook nil) (defun two-mode-mode-setup () (add-hook 'post-command-hook 'two-mode-mode-need-update nil t) (make-local-variable 'two-mode-bool) (setq two-mode-bool t) (make-local-variable 'two-mode-mode-idle-timer) (if two-mode-mode-idle-timer (cancel-timer two-mode-mode-idle-timer)) (setq two-mode-mode-idle-timer (run-with-idle-timer two-mode-mode-delay t 'two-mode-mode-update-mode)) (make-local-variable 'minor-mode-alist) (or (assq 'two-mode-bool minor-mode-alist) (setq minor-mode-alist (cons '(two-mode-bool " two-mode") minor-mode-alist)))) (defun two-mode-mode-need-update () (setq two-mode-update t)) (defun two-mode-change-mode (to-mode func) (let ((mode (if (listp mode-name) (car (last mode-name)) mode-name))) (if (string= to-mode mode) t (funcall func) ;; After the mode was set, we reread the "Local Variables" section. ;; We do need this for example in SGML-mode if "sgml-parent-document" ;; was set, or otherwise it will be reset to nil when sgml-mode is left. (hack-local-variables) (two-mode-mode-setup) (if two-mode-switch-hook (run-hooks 'two-mode-switch-hook)) (if (eq font-lock-mode t) (font-lock-fontify-buffer)) (if (fboundp 'turn-on-font-lock-if-enabled) (turn-on-font-lock-if-enabled) (turn-on-font-lock-if-desired))))) (defun two-mode-mode-update-mode () (when (and two-mode-bool two-mode-update) (setq two-mode-update 0) (let ((mode-list second-modes) (to-mode (car default-mode)) (func (cadr default-mode))) (while mode-list (let ((mode (car mode-list)) (lm -1) (rm -1)) (save-excursion (if (search-backward (cadr mode) nil t) (setq lm (point)))) (save-excursion (if (search-backward (car (cddr mode)) nil t) (setq rm (point)))) (if (and (not (and (= lm -1) (= rm -1))) (>= lm rm)) (progn (setq mode-list nil) (setq to-mode (car mode)) (setq func (car (cdr (cddr mode))))) (setq mode-list (cdr mode-list))))) (two-mode-change-mode to-mode func)))) (defun two-mode-mode () "Turn on two-mode-mode" (interactive) (setq two-mode-update t) (two-mode-mode-setup) (two-mode-mode-update-mode) (if two-mode-hook (run-hooks 'two-mode-hook))) (provide 'two-mode-mode) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/vsn.mk�����������������������������������������������������������������������������������0000664�0001750�0001750�00000000017�12605311413�010552� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������YAWS_VSN=2.0.2 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/configure��������������������������������������������������������������������������������0000775�0001750�0001750�00002161021�12605311445�011334� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for yaws 2.0.2. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 </dev/null exec 6>&1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='yaws' PACKAGE_TARNAME='yaws' PACKAGE_VERSION='2.0.2' PACKAGE_STRING='yaws 2.0.2' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="src/yaws_app.erl" # Factoring default headers for most tests. ac_includes_default="\ #include <stdio.h> #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> #endif #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif #ifdef STDC_HEADERS # include <stdlib.h> # include <stddef.h> #else # ifdef HAVE_STDLIB_H # include <stdlib.h> # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include <memory.h> # endif # include <string.h> #endif #ifdef HAVE_STRINGS_H # include <strings.h> #endif #ifdef HAVE_INTTYPES_H # include <inttypes.h> #endif #ifdef HAVE_STDINT_H # include <stdint.h> #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS CONFIG_STATUS_DEPENDENCIES yappdir yawsdir logdir appsdir wwwdir confdir INSTALL_BUILDER TODOS UNIX2DOS CURL CADAVER CAN_BUILD_DOC_FALSE CAN_BUILD_DOC_TRUE PS2PDF MAN EPSTOPDF PDFLATEX DVIPS DVILATEX HAVE_ERLANG_NOW HAVE_ERLANG_NOW_FALSE HAVE_ERLANG_NOW_TRUE HAVE_INET_PARSE_STRICT_ADDRESS HAVE_INET_PARSE_STRICT_ADDRESS_FALSE HAVE_INET_PARSE_STRICT_ADDRESS_TRUE HAVE_CRYPTO_HASH HAVE_CRYPTO_HASH_FALSE HAVE_CRYPTO_HASH_TRUE HAVE_ERLANG_SENDFILE HAVE_SENDFILE HAVE_ERLANG_SENDFILE_FALSE HAVE_ERLANG_SENDFILE_TRUE HAVE_SENDFILE_FALSE HAVE_SENDFILE_TRUE WINDOWS_FALSE WINDOWS_TRUE MINGW_FALSE MINGW_TRUE CYGWIN_FALSE CYGWIN_TRUE EPAM_CFLAGS WERL ERLANG_LIB_VER_inets ERLANG_LIB_DIR_inets ERLANG_LIB_VER_xmlrpc ERLANG_LIB_DIR_xmlrpc ERLANG_LIB_VER_erlsom ERLANG_LIB_DIR_erlsom ERLANG_LIB_VER_eunit ERLANG_LIB_DIR_eunit ERLANG_LIB_VER_mnesia ERLANG_LIB_DIR_mnesia ERLANG_LIB_VER_ssl ERLANG_LIB_DIR_ssl ERLANG_LIB_VER_public_key ERLANG_LIB_DIR_public_key ERLANG_LIB_VER_xmerl ERLANG_LIB_DIR_xmerl ERLANG_LIB_VER_crypto ERLANG_LIB_DIR_crypto ERLANG_LIB_VER_compiler ERLANG_LIB_DIR_compiler ERLANG_LIB_VER_erts ERLANG_LIB_DIR_erts ERLANG_LIB_VER_sasl ERLANG_LIB_DIR_sasl ERLANG_LIB_VER_stdlib ERLANG_LIB_DIR_stdlib ERLANG_LIB_VER_kernel ERLANG_LIB_DIR_kernel ERLANG_INSTALL_LIB_DIR_yapp YAPP_VSN ERLANG_INSTALL_LIB_DIR_yaws YAWS_VSN ERLANG_INSTALL_LIB_DIR HAVE_SSL_LOG_ALERT HAVE_SSL_LOG_ALERT_FALSE HAVE_SSL_LOG_ALERT_TRUE HAVE_SSL_CLIENT_RENEGOTIATION HAVE_SSL_CLIENT_RENEGOTIATION_FALSE HAVE_SSL_CLIENT_RENEGOTIATION_TRUE HAVE_SSL_HONOR_CIPHER_ORDER HAVE_SSL_HONOR_CIPHER_ORDER_FALSE HAVE_SSL_HONOR_CIPHER_ORDER_TRUE HAVE_BAD_WILDCARD HAVE_BAD_WILDCARD_FALSE HAVE_BAD_WILDCARD_TRUE HAVE_BAD_UNICODE HAVE_BAD_UNICODE_FALSE HAVE_BAD_UNICODE_TRUE ERLANG_RELEASE ERLANG_ERTS_VER ERLANG_ERTS_DIR ERLANG_LIB_DIR ERLANG_ROOT_DIR ERL_LIBS DIALYZER ESCRIPT ERLCFLAGS ERLC ERL APPDEPS WITH_EPAM_FALSE WITH_EPAM_TRUE EXTRAINCLUDE DEFAULT_CHARSET OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LIBTOOL LD FGREP SED EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC ac_ct_AR AR AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking with_gnu_ld enable_static enable_shared with_pic enable_fast_install with_sysroot enable_libtool_lock with_defaultcharset with_extrainclude enable_pam enable_crypto enable_compiler with_erlang ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP ERL ERLC ERLCFLAGS ESCRIPT DIALYZER ERL_LIBS ERLANG_INSTALL_LIB_DIR ERLANG_INSTALL_LIB_DIR_yaws ERLANG_INSTALL_LIB_DIR_yapp DVILATEX DVIPS PDFLATEX EPSTOPDF MAN PS2PDF CADAVER CURL UNIX2DOS TODOS INSTALL_BUILDER confdir wwwdir appsdir logdir yawsdir yappdir' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures yaws 2.0.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/yaws] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of yaws 2.0.2:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-static[=PKGS] build static libraries [default=no] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-pam disable pam auth --enable-crypto adds crypto application to yaws.app file --enable-compiler adds compiler application to yaws.app file Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-defaultcharset=CHARSET specify default charset, i.e UTF-8 --with-extrainclude=DIR dir to include if e.g. pam is installed in some odd place --with-erlang=PREFIX prefix where Erlang is installed (optional) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CPP C preprocessor ERL Erlang/OTP interpreter command [autodetected] ERLC Erlang/OTP compiler command [autodetected] ERLCFLAGS Erlang/OTP compiler flags [none] ESCRIPT Erlang/OTP interpreter command [autodetected] DIALYZER Erlang/OTP discrepancy analyzer [autodetected] ERL_LIBS Erlang/OTP applications search path [none] ERLANG_INSTALL_LIB_DIR Erlang/OTP library installation base directory [LIBDIR/erlang/lib] ERLANG_INSTALL_LIB_DIR_yaws Erlang/OTP 'yaws' library installation subdirectory [ERLANG_INSTALL_LIB_DIR/yaws-${YAWS_VSN}] ERLANG_INSTALL_LIB_DIR_yapp Erlang/OTP 'yapp' library installation subdirectory [ERLANG_INSTALL_LIB_DIR/yapp-${YAPP_VSN}] DVILATEX (pdf)latex command creating DVI file DVIPS dvips command PDFLATEX (pdf)latex command creating PDF file EPSTOPDF epstopdf command MAN man command creating manpages PS2PDF ps2pdf command creating PDF file CADAVER command-line WebDAV client for Unix CURL command-line tool for transferring data with URL syntax UNIX2DOS converts DOS <-> Unix text files TODOS converts DOS <-> Unix text files INSTALL_BUILDER BitRock InstallBuilder directory ['${HOME}/installbuilder-5.4.14'] confdir Default Yaws configuration directory ['$(sysconfdir)/yaws'] wwwdir Default Yaws docroot ['$(localstatedir)/yaws/www'] appsdir Default Yaws applications directory ['$(localstatedir)/yaws'] logdir Default Yaws log directory ['$(localstatedir)/log/yaws'] yawsdir Default Yaws installation directory ['$(libdir)/yaws']. If not specified, it is a link on '$(ERLANG_INSTALL_LIB_DIR_yaws)' yappdir Default Yapp installation directory ['$(libdir)/yapp']. If not specified, it is a link on '$(ERLANG_INSTALL_LIB_DIR_yapp)' Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF yaws configure 2.0.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case <limits.h> declares $2. For example, HP-UX 11i <limits.h> declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer <limits.h> to <assert.h> if __STDC__ is defined, since <limits.h> exists even on freestanding compilers. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_erl_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_erl_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_erl_try_run # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by yaws $as_me 2.0.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in ac-aux "$srcdir"/ac-aux; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in ac-aux \"$srcdir\"/ac-aux" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- cat >>confdefs.h <<_ACEOF #define CPU_VENDOR_OS "$host" _ACEOF am__api_version='1.14' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='yaws' VERSION='2.0.2' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: <http://www.gnu.org/software/coreutils/>. If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi ECHO=echo colored_echo_bold='' colored_echo_norm='' for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done if test x"$AWK" = x"not found"; then return fi case $TERM in xterm|xterm*|vt220|vt220*) colored_echo_bold=`$AWK 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null` colored_echo_norm=`$AWK 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null` ;; vt100|vt100*|cygwin) colored_echo_bold=`$AWK 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null` colored_echo_norm=`$AWK 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null` ;; *) paths=`$ECHO $PATH | sed -e 's/:/ /g'` for tool in tput tcout; do for dir in $paths; do if test -r "$dir/$tool" ; then for seq in bold md smso; do bold="`$dir/$tool $seq 2>/dev/null`" if test ".$bold" != . ; then colored_echo_bold="$bold" break fi done if test ".$colored_echo_bold" != . ; then for seq in sgr0 me rmso init reset; do norm="`$dir/$tool $seq 2>/dev/null`" if test ".$norm" != . ; then colored_echo_norm="$norm" break fi done fi break fi done if test x"$colored_echo_bold" != "x" -a x"$colored_echo_norm" != "x"; then break; fi done ;; esac old_cflags="$CFLAGS" # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdio.h> int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdarg.h> #include <stdio.h> struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 $as_echo_n "checking the archiver ($AR) interface... " >&6; } if ${am_cv_ar_interface+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 $as_echo "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdarg.h> #include <stdio.h> struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since # <limits.h> exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <ac_nonexistent.h> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since # <limits.h> exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <ac_nonexistent.h> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" if test $ac_cv_c_compiler_gnu = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 $as_echo_n "checking whether $CC needs -traditional... " >&6; } if ${ac_cv_prog_gcc_traditional+:} false; then : $as_echo_n "(cached) " >&6 else ac_pattern="Autoconf.*'x'" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <sgtty.h> Autoconf TIOCGETP _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes else ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <termio.h> Autoconf TCGETA _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 $as_echo "$ac_cv_prog_gcc_traditional" >&6; } if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in *GNU* | *'with BFD'*) test "$with_gnu_ld" != no && break ;; *) test "$with_gnu_ld" != yes && break ;; esac fi done IFS="$lt_save_ifs" else lt_cv_path_LD="$LD" # Let the user override the test with a path. fi fi LD="$lt_cv_path_LD" if test -n "$LD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 </dev/null` in *GNU* | *'with BFD'*) lt_cv_prog_gnu_ld=yes ;; *) lt_cv_prog_gnu_ld=no ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=no fi # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <float.h> int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <string.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdlib.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <ctype.h> #include <stdlib.h> #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach <jrb3@best.com> says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib<name>.so # instead of lib<name>.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include <dlfcn.h> #endif #include <stdio.h> #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include <dlfcn.h> #endif #include <stdio.h> #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: CFLAGS="-Werror -Wall -O3 $old_cflags" # Check whether --with-defaultcharset was given. if test "${with_defaultcharset+set}" = set; then : withval=$with_defaultcharset; with_defaultcharset=${withval%/} else with_defaultcharset="" fi if test "x${with_defaultcharset}" = "x"; then DEFAULT_CHARSET=undefined else DEFAULT_CHARSET="\"${with_defaultcharset}\"" fi # Check whether --with-extrainclude was given. if test "${with_extrainclude+set}" = set; then : withval=$with_extrainclude; with_extrainclude=${withval%/} else with_extrainclude="" fi if test "x$with_extrainclude" = "x" ; then EXTRAINCLUDE= else EXTRAINCLUDE=-I${with_extrainclude} fi # Check whether --enable-pam was given. if test "${enable_pam+set}" = set; then : enableval=$enable_pam; enable_pam="$enableval" else enable_pam="yes" fi if test "x${enable_pam}" = "xyes"; then WITH_EPAM_TRUE= WITH_EPAM_FALSE='#' else WITH_EPAM_TRUE='#' WITH_EPAM_FALSE= fi APPDEPS= # Check whether --enable-crypto was given. if test "${enable_crypto+set}" = set; then : enableval=$enable_crypto; fi if test "x$enable_crypto" = "xyes"; then APPDEPS=',crypto' fi # Check whether --enable-compiler was given. if test "${enable_compiler+set}" = set; then : enableval=$enable_compiler; fi if test "x$enable_compiler" = "xyes"; then APPDEPS="${APPDEPS},compiler" fi echo text=`$ECHO $seo "%BCheck Erlang environment & applications%b" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec "%BCheck Erlang environment & applications%b" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 tmp_cross_compiling=$cross_compiling cross_compiling=no # Check whether --with-erlang was given. if test "${with_erlang+set}" = set; then : withval=$with_erlang; with_erlang=${withval%/} else with_erlang="" fi if test "x${with_erlang}" = "x"; then if test -n "$ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erl" >&5 $as_echo_n "checking for erl... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5 $as_echo "$ERL" >&6; } else if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}erl", so it can be a program name with args. set dummy ${ac_tool_prefix}erl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ERL+:} false; then : $as_echo_n "(cached) " >&6 else case $ERL in [\\/]* | ?:[\\/]*) ac_cv_path_ERL="$ERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ERL=$ac_cv_path_ERL if test -n "$ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5 $as_echo "$ERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_ERL"; then ac_pt_ERL=$ERL # Extract the first word of "erl", so it can be a program name with args. set dummy erl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_ERL+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_ERL in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_ERL="$ac_pt_ERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_ERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_ERL=$ac_cv_path_ac_pt_ERL if test -n "$ac_pt_ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERL" >&5 $as_echo "$ac_pt_ERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_ERL" = x; then ERL="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac ERL=$ac_pt_ERL fi else ERL="$ac_cv_path_ERL" fi fi if test -n "$ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erlc" >&5 $as_echo_n "checking for erlc... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5 $as_echo "$ERLC" >&6; } else if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}erlc", so it can be a program name with args. set dummy ${ac_tool_prefix}erlc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ERLC+:} false; then : $as_echo_n "(cached) " >&6 else case $ERLC in [\\/]* | ?:[\\/]*) ac_cv_path_ERLC="$ERLC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ERLC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ERLC=$ac_cv_path_ERLC if test -n "$ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5 $as_echo "$ERLC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_ERLC"; then ac_pt_ERLC=$ERLC # Extract the first word of "erlc", so it can be a program name with args. set dummy erlc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_ERLC+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_ERLC in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_ERLC="$ac_pt_ERLC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_ERLC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_ERLC=$ac_cv_path_ac_pt_ERLC if test -n "$ac_pt_ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERLC" >&5 $as_echo "$ac_pt_ERLC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_ERLC" = x; then ERLC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac ERLC=$ac_pt_ERLC fi else ERLC="$ac_cv_path_ERLC" fi fi else erl_path="${with_erlang}/bin" if test -n "$ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erl" >&5 $as_echo_n "checking for erl... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5 $as_echo "$ERL" >&6; } else if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}erl", so it can be a program name with args. set dummy ${ac_tool_prefix}erl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ERL+:} false; then : $as_echo_n "(cached) " >&6 else case $ERL in [\\/]* | ?:[\\/]*) ac_cv_path_ERL="$ERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $erl_path$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ERL=$ac_cv_path_ERL if test -n "$ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5 $as_echo "$ERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_ERL"; then ac_pt_ERL=$ERL # Extract the first word of "erl", so it can be a program name with args. set dummy erl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_ERL+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_ERL in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_ERL="$ac_pt_ERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $erl_path$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_ERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_ERL=$ac_cv_path_ac_pt_ERL if test -n "$ac_pt_ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERL" >&5 $as_echo "$ac_pt_ERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_ERL" = x; then ERL="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac ERL=$ac_pt_ERL fi else ERL="$ac_cv_path_ERL" fi fi if test -n "$ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erlc" >&5 $as_echo_n "checking for erlc... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5 $as_echo "$ERLC" >&6; } else if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}erlc", so it can be a program name with args. set dummy ${ac_tool_prefix}erlc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ERLC+:} false; then : $as_echo_n "(cached) " >&6 else case $ERLC in [\\/]* | ?:[\\/]*) ac_cv_path_ERLC="$ERLC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $erl_path$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ERLC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ERLC=$ac_cv_path_ERLC if test -n "$ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5 $as_echo "$ERLC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_ERLC"; then ac_pt_ERLC=$ERLC # Extract the first word of "erlc", so it can be a program name with args. set dummy erlc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_ERLC+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_ERLC in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_ERLC="$ac_pt_ERLC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $erl_path$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_ERLC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_ERLC=$ac_cv_path_ac_pt_ERLC if test -n "$ac_pt_ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERLC" >&5 $as_echo "$ac_pt_ERLC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_ERLC" = x; then ERLC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac ERLC=$ac_pt_ERLC fi else ERLC="$ac_cv_path_ERLC" fi fi fi if test "x${ERL}" = "x"; then as_fn_error $? " Erlang not found. Fill the ERL variable with erl(1) path or provide Erlang prefix with --with-erlang." "$LINENO" 5 fi if test "x${ESCRIPT}" = "x"; then if test "x${with_erlang}" = "x"; then # Extract the first word of "escript", so it can be a program name with args. set dummy escript; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ESCRIPT+:} false; then : $as_echo_n "(cached) " >&6 else case $ESCRIPT in [\\/]* | ?:[\\/]*) ac_cv_path_ESCRIPT="$ESCRIPT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ESCRIPT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ESCRIPT=$ac_cv_path_ESCRIPT if test -n "$ESCRIPT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ESCRIPT" >&5 $as_echo "$ESCRIPT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else erl_path="${with_erlang}/bin" # Extract the first word of "escript", so it can be a program name with args. set dummy escript; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ESCRIPT+:} false; then : $as_echo_n "(cached) " >&6 else case $ESCRIPT in [\\/]* | ?:[\\/]*) ac_cv_path_ESCRIPT="$ESCRIPT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $erl_path$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ESCRIPT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ESCRIPT=$ac_cv_path_ESCRIPT if test -n "$ESCRIPT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ESCRIPT" >&5 $as_echo "$ESCRIPT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for escript" >&5 $as_echo_n "checking for escript... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ESCRIPT" >&5 $as_echo "$ESCRIPT" >&6; } fi if test "x${ESCRIPT}" = "x"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: escript(1) not found. Fill the ESCRIPT variable with escript(1) path if you want to use the testsuite." >&5 $as_echo "$as_me: WARNING: escript(1) not found. Fill the ESCRIPT variable with escript(1) path if you want to use the testsuite." >&2;} fi if test "x${DIALYZER}" = "x"; then if test "x${with_erlang}" = "x"; then # Extract the first word of "dialyzer", so it can be a program name with args. set dummy dialyzer; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DIALYZER+:} false; then : $as_echo_n "(cached) " >&6 else case $DIALYZER in [\\/]* | ?:[\\/]*) ac_cv_path_DIALYZER="$DIALYZER" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DIALYZER="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DIALYZER=$ac_cv_path_DIALYZER if test -n "$DIALYZER"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DIALYZER" >&5 $as_echo "$DIALYZER" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else erl_path="${with_erlang}/bin" # Extract the first word of "dialyzer", so it can be a program name with args. set dummy dialyzer; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DIALYZER+:} false; then : $as_echo_n "(cached) " >&6 else case $DIALYZER in [\\/]* | ?:[\\/]*) ac_cv_path_DIALYZER="$DIALYZER" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $erl_path$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DIALYZER="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DIALYZER=$ac_cv_path_DIALYZER if test -n "$DIALYZER"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DIALYZER" >&5 $as_echo "$DIALYZER" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dialyzer" >&5 $as_echo_n "checking for dialyzer... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DIALYZER" >&5 $as_echo "$DIALYZER" >&6; } fi if test "x${DIALYZER}" = "x"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: dialyzer(1) not found. Fill the DIALYZER variable with dialyzer(1) path if you want to use it." >&5 $as_echo "$as_me: WARNING: dialyzer(1) not found. Fill the DIALYZER variable with dialyzer(1) path if you want to use it." >&2;} fi if test -n "$ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erlc" >&5 $as_echo_n "checking for erlc... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5 $as_echo "$ERLC" >&6; } else if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}erlc", so it can be a program name with args. set dummy ${ac_tool_prefix}erlc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ERLC+:} false; then : $as_echo_n "(cached) " >&6 else case $ERLC in [\\/]* | ?:[\\/]*) ac_cv_path_ERLC="$ERLC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ERLC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ERLC=$ac_cv_path_ERLC if test -n "$ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5 $as_echo "$ERLC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_ERLC"; then ac_pt_ERLC=$ERLC # Extract the first word of "erlc", so it can be a program name with args. set dummy erlc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_ERLC+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_ERLC in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_ERLC="$ac_pt_ERLC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_ERLC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_ERLC=$ac_cv_path_ac_pt_ERLC if test -n "$ac_pt_ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERLC" >&5 $as_echo "$ac_pt_ERLC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_ERLC" = x; then ERLC="not found" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac ERLC=$ac_pt_ERLC fi else ERLC="$ac_cv_path_ERLC" fi fi if test "$ERLC" = "not found"; then as_fn_error $? "Erlang/OTP compiler (erlc) not found but required" "$LINENO" 5 fi if test -n "$ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erl" >&5 $as_echo_n "checking for erl... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5 $as_echo "$ERL" >&6; } else if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}erl", so it can be a program name with args. set dummy ${ac_tool_prefix}erl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ERL+:} false; then : $as_echo_n "(cached) " >&6 else case $ERL in [\\/]* | ?:[\\/]*) ac_cv_path_ERL="$ERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ERL=$ac_cv_path_ERL if test -n "$ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5 $as_echo "$ERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_ERL"; then ac_pt_ERL=$ERL # Extract the first word of "erl", so it can be a program name with args. set dummy erl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_ERL+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_ERL in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_ERL="$ac_pt_ERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_ERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_ERL=$ac_cv_path_ac_pt_ERL if test -n "$ac_pt_ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERL" >&5 $as_echo "$ac_pt_ERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_ERL" = x; then ERL="not found" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac ERL=$ac_pt_ERL fi else ERL="$ac_cv_path_ERL" fi fi if test "$ERL" = "not found"; then as_fn_error $? "Erlang/OTP interpreter (erl) not found but required" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP root directory" >&5 $as_echo_n "checking for Erlang/OTP root directory... " >&6; } if ${ac_cv_erlang_root_dir+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> RootDir = code:root_dir(), file:write_file("conftest.out", RootDir), ReturnValue = 0, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_root_dir=`cat conftest.out` rm -f conftest.out else rm -f conftest.out { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_root_dir" >&5 $as_echo "$ac_cv_erlang_root_dir" >&6; } ERLANG_ROOT_DIR=$ac_cv_erlang_root_dir { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP library base directory" >&5 $as_echo_n "checking for Erlang/OTP library base directory... " >&6; } if ${ac_cv_erlang_lib_dir+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> LibDir = code:lib_dir(), file:write_file("conftest.out", LibDir), ReturnValue = 0, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir=`cat conftest.out` rm -f conftest.out else rm -f conftest.out { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir" >&5 $as_echo "$ac_cv_erlang_lib_dir" >&6; } ERLANG_LIB_DIR=$ac_cv_erlang_lib_dir { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP ERTS version" >&5 $as_echo_n "checking for Erlang/OTP ERTS version... " >&6; } if ${erlang_cv_erts_ver+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> file:write_file("conftest.out", erlang:system_info(version)), halt(0) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : erlang_cv_erts_ver=`cat conftest.out` else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else erlang_cv_erts_ver="not found" fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $erlang_cv_erts_ver" >&5 $as_echo "$erlang_cv_erts_ver" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP ERTS directory" >&5 $as_echo_n "checking for Erlang/OTP ERTS directory... " >&6; } if ${erlang_cv_erts_dir+:} false; then : $as_echo_n "(cached) " >&6 else erlang_cv_erts_dir="${ERLANG_ROOT_DIR}/erts-$erlang_cv_erts_ver" if test ! -d "$erlang_cv_erts_dir"; then erlang_cv_erts_dir="${ERLANG_ROOT_DIR}/usr" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $erlang_cv_erts_dir" >&5 $as_echo "$erlang_cv_erts_dir" >&6; } ERLANG_ERTS_DIR=$erlang_cv_erts_dir ERLANG_ERTS_VER=$erlang_cv_erts_ver if test "$erlang_cv_erts_ver" = "not found"; then : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP release" >&5 $as_echo_n "checking for Erlang/OTP release... " >&6; } if ${erlang_cv_release+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> file:write_file("conftest.out", erlang:system_info(otp_release)), halt(0) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : erlang_cv_release=`cat conftest.out` else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else erlang_cv_release="not found" fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $erlang_cv_release" >&5 $as_echo "$erlang_cv_release" >&6; } ERLANG_RELEASE=$erlang_cv_release # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. ax_compare_version_A=`echo "${ERLANG_ERTS_VER}" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version_B=`echo "5.8.3" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version=`echo "x$ax_compare_version_A x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` if test "$ax_compare_version" = "true" ; then : else as_fn_error $? "Erlang R14B02 or higher is required but only Erlang $ERLANG_RELEASE was found!" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for buggy unicode module" >&5 $as_echo_n "checking for buggy unicode module... " >&6; } # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. ax_compare_version_A=`echo "${ERLANG_ERTS_VER}" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version_B=`echo "5.8.5" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version=`echo "x$ax_compare_version_A x$ax_compare_version_B" | sed 's/^ *//' | sort | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` if test "$ax_compare_version" = "true" ; then bad_unicode="yes" else bad_unicode="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${bad_unicode}" >&5 $as_echo "${bad_unicode}" >&6; } HAVE_BAD_UNICODE=false if test "x${bad_unicode}" = "xyes"; then HAVE_BAD_UNICODE=true fi if test "x$HAVE_BAD_UNICODE" = "xtrue"; then HAVE_BAD_UNICODE_TRUE= HAVE_BAD_UNICODE_FALSE='#' else HAVE_BAD_UNICODE_TRUE='#' HAVE_BAD_UNICODE_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for buggy filelib:wildcard/2 function" >&5 $as_echo_n "checking for buggy filelib:wildcard/2 function... " >&6; } # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. ax_compare_version_A=`echo "${ERLANG_ERTS_VER}" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version_B=`echo "5.9.3" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version=`echo "x$ax_compare_version_A x$ax_compare_version_B" | sed 's/^ *//' | sort | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` if test "$ax_compare_version" = "true" ; then bad_wildcard="yes" else bad_wildcard="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${bad_wildcard}" >&5 $as_echo "${bad_wildcard}" >&6; } HAVE_BAD_WILDCARD=false if test "x${bad_wildcard}" = "xyes"; then HAVE_BAD_WILDCARD=true fi if test "x$HAVE_BAD_WILDCARD" = "xtrue"; then HAVE_BAD_WILDCARD_TRUE= HAVE_BAD_WILDCARD_FALSE='#' else HAVE_BAD_WILDCARD_TRUE='#' HAVE_BAD_WILDCARD_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for support of honor_cipher_order SSL option" >&5 $as_echo_n "checking for support of honor_cipher_order SSL option... " >&6; } # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. ax_compare_version_A=`echo "${ERLANG_ERTS_VER}" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version_B=`echo "6.0" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version=`echo "x$ax_compare_version_A x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` if test "$ax_compare_version" = "true" ; then ssl_honor_cipher_order="yes" else ssl_honor_cipher_order="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ssl_honor_cipher_order}" >&5 $as_echo "${ssl_honor_cipher_order}" >&6; } HAVE_SSL_HONOR_CIPHER_ORDER=false if test "x${ssl_honor_cipher_order}" = "xyes"; then HAVE_SSL_HONOR_CIPHER_ORDER=true fi if test "x$HAVE_SSL_HONOR_CIPHER_ORDER" = "xtrue"; then HAVE_SSL_HONOR_CIPHER_ORDER_TRUE= HAVE_SSL_HONOR_CIPHER_ORDER_FALSE='#' else HAVE_SSL_HONOR_CIPHER_ORDER_TRUE='#' HAVE_SSL_HONOR_CIPHER_ORDER_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for support of client_renegotiation SSL option" >&5 $as_echo_n "checking for support of client_renegotiation SSL option... " >&6; } # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. ax_compare_version_A=`echo "${ERLANG_ERTS_VER}" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version_B=`echo "7.0" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version=`echo "x$ax_compare_version_A x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` if test "$ax_compare_version" = "true" ; then ssl_client_renegotiation="yes" else ssl_client_renegotiation="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ssl_client_renegotiation}" >&5 $as_echo "${ssl_client_renegotiation}" >&6; } HAVE_SSL_CLIENT_RENEGOTIATION=false if test "x${ssl_client_renegotiation}" = "xyes"; then HAVE_SSL_CLIENT_RENEGOTIATION=true fi if test "x$HAVE_SSL_CLIENT_RENEGOTIATION" = "xtrue"; then HAVE_SSL_CLIENT_RENEGOTIATION_TRUE= HAVE_SSL_CLIENT_RENEGOTIATION_FALSE='#' else HAVE_SSL_CLIENT_RENEGOTIATION_TRUE='#' HAVE_SSL_CLIENT_RENEGOTIATION_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for support of log_alert SSL option" >&5 $as_echo_n "checking for support of log_alert SSL option... " >&6; } # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. ax_compare_version_A=`echo "${ERLANG_ERTS_VER}" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version_B=`echo "5.10.3" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version=`echo "x$ax_compare_version_A x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` if test "$ax_compare_version" = "true" ; then ssl_log_alert="yes" else ssl_log_alert="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ssl_log_alert}" >&5 $as_echo "${ssl_log_alert}" >&6; } HAVE_SSL_LOG_ALERT=false if test "x${ssl_log_alert}" = "xyes"; then HAVE_SSL_LOG_ALERT=true fi if test "x$HAVE_SSL_LOG_ALERT" = "xtrue"; then HAVE_SSL_LOG_ALERT_TRUE= HAVE_SSL_LOG_ALERT_FALSE='#' else HAVE_SSL_LOG_ALERT_TRUE='#' HAVE_SSL_LOG_ALERT_FALSE= fi if test "x${prefix}" != "xNONE" -a "x${ERLANG_INSTALL_LIB_DIR}" = "x"; then ERLANG_INSTALL_LIB_DIR='${prefix}/lib' else ERLANG_INSTALL_LIB_DIR='${ERLANG_LIB_DIR}' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP library installation base directory" >&5 $as_echo_n "checking for Erlang/OTP library installation base directory... " >&6; } if test -n "$ERLANG_INSTALL_LIB_DIR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLANG_INSTALL_LIB_DIR" >&5 $as_echo "$ERLANG_INSTALL_LIB_DIR" >&6; } else ERLANG_INSTALL_LIB_DIR='${libdir}/erlang/lib' { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libdir/erlang/lib" >&5 $as_echo "$libdir/erlang/lib" >&6; } fi . ${srcdir}/vsn.mk { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'yaws' library installation subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'yaws' library installation subdirectory... " >&6; } if test -n "$ERLANG_INSTALL_LIB_DIR_yaws"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLANG_INSTALL_LIB_DIR_yaws" >&5 $as_echo "$ERLANG_INSTALL_LIB_DIR_yaws" >&6; } else ERLANG_INSTALL_LIB_DIR_yaws='${ERLANG_INSTALL_LIB_DIR}/yaws-${YAWS_VSN}' { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLANG_INSTALL_LIB_DIR/yaws-${YAWS_VSN}" >&5 $as_echo "$ERLANG_INSTALL_LIB_DIR/yaws-${YAWS_VSN}" >&6; } fi . ${srcdir}/applications/yapp/vsn.mk { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'yapp' library installation subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'yapp' library installation subdirectory... " >&6; } if test -n "$ERLANG_INSTALL_LIB_DIR_yapp"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLANG_INSTALL_LIB_DIR_yapp" >&5 $as_echo "$ERLANG_INSTALL_LIB_DIR_yapp" >&6; } else ERLANG_INSTALL_LIB_DIR_yapp='${ERLANG_INSTALL_LIB_DIR}/yapp-${YAPP_VSN}' { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLANG_INSTALL_LIB_DIR/yapp-${YAPP_VSN}" >&5 $as_echo "$ERLANG_INSTALL_LIB_DIR/yapp-${YAPP_VSN}" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'kernel' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'kernel' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_kernel+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("kernel") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_kernel=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_kernel="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_kernel" >&5 $as_echo "$ac_cv_erlang_lib_dir_kernel" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'kernel' library version" >&5 $as_echo_n "checking for Erlang/OTP 'kernel' library version... " >&6; } if ${ac_cv_erlang_lib_ver_kernel+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_kernel" = "not found"; then : ac_cv_erlang_lib_ver_kernel="not found" else ac_cv_erlang_lib_ver_kernel=`$as_echo "$ac_cv_erlang_lib_dir_kernel" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_kernel" >&5 $as_echo "$ac_cv_erlang_lib_ver_kernel" >&6; } ERLANG_LIB_DIR_kernel=$ac_cv_erlang_lib_dir_kernel ERLANG_LIB_VER_kernel=$ac_cv_erlang_lib_ver_kernel if test "$ac_cv_erlang_lib_dir_kernel" = "not found"; then : as_fn_error $? "\"kernel\" Erlang application not found." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'stdlib' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'stdlib' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_stdlib+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("stdlib") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_stdlib=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_stdlib="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_stdlib" >&5 $as_echo "$ac_cv_erlang_lib_dir_stdlib" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'stdlib' library version" >&5 $as_echo_n "checking for Erlang/OTP 'stdlib' library version... " >&6; } if ${ac_cv_erlang_lib_ver_stdlib+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_stdlib" = "not found"; then : ac_cv_erlang_lib_ver_stdlib="not found" else ac_cv_erlang_lib_ver_stdlib=`$as_echo "$ac_cv_erlang_lib_dir_stdlib" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_stdlib" >&5 $as_echo "$ac_cv_erlang_lib_ver_stdlib" >&6; } ERLANG_LIB_DIR_stdlib=$ac_cv_erlang_lib_dir_stdlib ERLANG_LIB_VER_stdlib=$ac_cv_erlang_lib_ver_stdlib if test "$ac_cv_erlang_lib_dir_stdlib" = "not found"; then : as_fn_error $? "\"stdlib\" Erlang application not found." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'sasl' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'sasl' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_sasl+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("sasl") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_sasl=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_sasl="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_sasl" >&5 $as_echo "$ac_cv_erlang_lib_dir_sasl" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'sasl' library version" >&5 $as_echo_n "checking for Erlang/OTP 'sasl' library version... " >&6; } if ${ac_cv_erlang_lib_ver_sasl+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_sasl" = "not found"; then : ac_cv_erlang_lib_ver_sasl="not found" else ac_cv_erlang_lib_ver_sasl=`$as_echo "$ac_cv_erlang_lib_dir_sasl" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_sasl" >&5 $as_echo "$ac_cv_erlang_lib_ver_sasl" >&6; } ERLANG_LIB_DIR_sasl=$ac_cv_erlang_lib_dir_sasl ERLANG_LIB_VER_sasl=$ac_cv_erlang_lib_ver_sasl if test "$ac_cv_erlang_lib_dir_sasl" = "not found"; then : as_fn_error $? "\"compiler\" Erlang application not found." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'erts' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'erts' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_erts+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("erts") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_erts=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_erts="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_erts" >&5 $as_echo "$ac_cv_erlang_lib_dir_erts" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'erts' library version" >&5 $as_echo_n "checking for Erlang/OTP 'erts' library version... " >&6; } if ${ac_cv_erlang_lib_ver_erts+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_erts" = "not found"; then : ac_cv_erlang_lib_ver_erts="not found" else ac_cv_erlang_lib_ver_erts=`$as_echo "$ac_cv_erlang_lib_dir_erts" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_erts" >&5 $as_echo "$ac_cv_erlang_lib_ver_erts" >&6; } ERLANG_LIB_DIR_erts=$ac_cv_erlang_lib_dir_erts ERLANG_LIB_VER_erts=$ac_cv_erlang_lib_ver_erts if test "$ac_cv_erlang_lib_dir_erts" = "not found"; then : as_fn_error $? "\"compiler\" Erlang application not found." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'compiler' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'compiler' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_compiler+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("compiler") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_compiler=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_compiler="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_compiler" >&5 $as_echo "$ac_cv_erlang_lib_dir_compiler" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'compiler' library version" >&5 $as_echo_n "checking for Erlang/OTP 'compiler' library version... " >&6; } if ${ac_cv_erlang_lib_ver_compiler+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_compiler" = "not found"; then : ac_cv_erlang_lib_ver_compiler="not found" else ac_cv_erlang_lib_ver_compiler=`$as_echo "$ac_cv_erlang_lib_dir_compiler" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_compiler" >&5 $as_echo "$ac_cv_erlang_lib_ver_compiler" >&6; } ERLANG_LIB_DIR_compiler=$ac_cv_erlang_lib_dir_compiler ERLANG_LIB_VER_compiler=$ac_cv_erlang_lib_ver_compiler if test "$ac_cv_erlang_lib_dir_compiler" = "not found"; then : as_fn_error $? "\"compiler\" Erlang application not found." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'crypto' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'crypto' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_crypto+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("crypto") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_crypto=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_crypto="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_crypto" >&5 $as_echo "$ac_cv_erlang_lib_dir_crypto" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'crypto' library version" >&5 $as_echo_n "checking for Erlang/OTP 'crypto' library version... " >&6; } if ${ac_cv_erlang_lib_ver_crypto+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_crypto" = "not found"; then : ac_cv_erlang_lib_ver_crypto="not found" else ac_cv_erlang_lib_ver_crypto=`$as_echo "$ac_cv_erlang_lib_dir_crypto" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_crypto" >&5 $as_echo "$ac_cv_erlang_lib_ver_crypto" >&6; } ERLANG_LIB_DIR_crypto=$ac_cv_erlang_lib_dir_crypto ERLANG_LIB_VER_crypto=$ac_cv_erlang_lib_ver_crypto if test "$ac_cv_erlang_lib_dir_crypto" = "not found"; then : as_fn_error $? "\"crypto\" Erlang application not found." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'xmerl' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'xmerl' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_xmerl+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("xmerl") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_xmerl=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_xmerl="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_xmerl" >&5 $as_echo "$ac_cv_erlang_lib_dir_xmerl" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'xmerl' library version" >&5 $as_echo_n "checking for Erlang/OTP 'xmerl' library version... " >&6; } if ${ac_cv_erlang_lib_ver_xmerl+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_xmerl" = "not found"; then : ac_cv_erlang_lib_ver_xmerl="not found" else ac_cv_erlang_lib_ver_xmerl=`$as_echo "$ac_cv_erlang_lib_dir_xmerl" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_xmerl" >&5 $as_echo "$ac_cv_erlang_lib_ver_xmerl" >&6; } ERLANG_LIB_DIR_xmerl=$ac_cv_erlang_lib_dir_xmerl ERLANG_LIB_VER_xmerl=$ac_cv_erlang_lib_ver_xmerl if test "$ac_cv_erlang_lib_dir_xmerl" = "not found"; then : as_fn_error $? "\"xmerl\" Erlang application not found." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'public_key' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'public_key' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_public_key+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("public_key") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_public_key=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_public_key="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_public_key" >&5 $as_echo "$ac_cv_erlang_lib_dir_public_key" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'public_key' library version" >&5 $as_echo_n "checking for Erlang/OTP 'public_key' library version... " >&6; } if ${ac_cv_erlang_lib_ver_public_key+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_public_key" = "not found"; then : ac_cv_erlang_lib_ver_public_key="not found" else ac_cv_erlang_lib_ver_public_key=`$as_echo "$ac_cv_erlang_lib_dir_public_key" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_public_key" >&5 $as_echo "$ac_cv_erlang_lib_ver_public_key" >&6; } ERLANG_LIB_DIR_public_key=$ac_cv_erlang_lib_dir_public_key ERLANG_LIB_VER_public_key=$ac_cv_erlang_lib_ver_public_key if test "$ac_cv_erlang_lib_dir_public_key" = "not found"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"public_key\" Erlang application not found. It could be required to run Yaws or its testsuites." >&5 $as_echo "$as_me: WARNING: \"public_key\" Erlang application not found. It could be required to run Yaws or its testsuites." >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'ssl' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'ssl' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_ssl+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("ssl") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_ssl=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_ssl="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_ssl" >&5 $as_echo "$ac_cv_erlang_lib_dir_ssl" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'ssl' library version" >&5 $as_echo_n "checking for Erlang/OTP 'ssl' library version... " >&6; } if ${ac_cv_erlang_lib_ver_ssl+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_ssl" = "not found"; then : ac_cv_erlang_lib_ver_ssl="not found" else ac_cv_erlang_lib_ver_ssl=`$as_echo "$ac_cv_erlang_lib_dir_ssl" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_ssl" >&5 $as_echo "$ac_cv_erlang_lib_ver_ssl" >&6; } ERLANG_LIB_DIR_ssl=$ac_cv_erlang_lib_dir_ssl ERLANG_LIB_VER_ssl=$ac_cv_erlang_lib_ver_ssl if test "$ac_cv_erlang_lib_dir_ssl" = "not found"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"ssl\" Erlang application not found. It could be required to run Yaws or its testsuites." >&5 $as_echo "$as_me: WARNING: \"ssl\" Erlang application not found. It could be required to run Yaws or its testsuites." >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'mnesia' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'mnesia' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_mnesia+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("mnesia") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_mnesia=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_mnesia="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_mnesia" >&5 $as_echo "$ac_cv_erlang_lib_dir_mnesia" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'mnesia' library version" >&5 $as_echo_n "checking for Erlang/OTP 'mnesia' library version... " >&6; } if ${ac_cv_erlang_lib_ver_mnesia+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_mnesia" = "not found"; then : ac_cv_erlang_lib_ver_mnesia="not found" else ac_cv_erlang_lib_ver_mnesia=`$as_echo "$ac_cv_erlang_lib_dir_mnesia" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_mnesia" >&5 $as_echo "$ac_cv_erlang_lib_ver_mnesia" >&6; } ERLANG_LIB_DIR_mnesia=$ac_cv_erlang_lib_dir_mnesia ERLANG_LIB_VER_mnesia=$ac_cv_erlang_lib_ver_mnesia if test "$ac_cv_erlang_lib_dir_mnesia" = "not found"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"mnesia\" Erlang application not found. It could be required to run Yaws or its testsuites." >&5 $as_echo "$as_me: WARNING: \"mnesia\" Erlang application not found. It could be required to run Yaws or its testsuites." >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'eunit' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'eunit' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_eunit+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("eunit") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_eunit=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_eunit="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_eunit" >&5 $as_echo "$ac_cv_erlang_lib_dir_eunit" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'eunit' library version" >&5 $as_echo_n "checking for Erlang/OTP 'eunit' library version... " >&6; } if ${ac_cv_erlang_lib_ver_eunit+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_eunit" = "not found"; then : ac_cv_erlang_lib_ver_eunit="not found" else ac_cv_erlang_lib_ver_eunit=`$as_echo "$ac_cv_erlang_lib_dir_eunit" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_eunit" >&5 $as_echo "$ac_cv_erlang_lib_ver_eunit" >&6; } ERLANG_LIB_DIR_eunit=$ac_cv_erlang_lib_dir_eunit ERLANG_LIB_VER_eunit=$ac_cv_erlang_lib_ver_eunit if test "$ac_cv_erlang_lib_dir_eunit" = "not found"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"eunit\" Erlang application not found. It could be required to run Yaws or its testsuites." >&5 $as_echo "$as_me: WARNING: \"eunit\" Erlang application not found. It could be required to run Yaws or its testsuites." >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'erlsom' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'erlsom' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_erlsom+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("erlsom") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_erlsom=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_erlsom="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_erlsom" >&5 $as_echo "$ac_cv_erlang_lib_dir_erlsom" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'erlsom' library version" >&5 $as_echo_n "checking for Erlang/OTP 'erlsom' library version... " >&6; } if ${ac_cv_erlang_lib_ver_erlsom+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_erlsom" = "not found"; then : ac_cv_erlang_lib_ver_erlsom="not found" else ac_cv_erlang_lib_ver_erlsom=`$as_echo "$ac_cv_erlang_lib_dir_erlsom" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_erlsom" >&5 $as_echo "$ac_cv_erlang_lib_ver_erlsom" >&6; } ERLANG_LIB_DIR_erlsom=$ac_cv_erlang_lib_dir_erlsom ERLANG_LIB_VER_erlsom=$ac_cv_erlang_lib_ver_erlsom if test "$ac_cv_erlang_lib_dir_erlsom" = "not found"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"erlsom\" Erlang application not found. It could be required to run Yaws or its testsuites." >&5 $as_echo "$as_me: WARNING: \"erlsom\" Erlang application not found. It could be required to run Yaws or its testsuites." >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'xmlrpc' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'xmlrpc' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_xmlrpc+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("xmlrpc") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_xmlrpc=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_xmlrpc="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_xmlrpc" >&5 $as_echo "$ac_cv_erlang_lib_dir_xmlrpc" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'xmlrpc' library version" >&5 $as_echo_n "checking for Erlang/OTP 'xmlrpc' library version... " >&6; } if ${ac_cv_erlang_lib_ver_xmlrpc+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_xmlrpc" = "not found"; then : ac_cv_erlang_lib_ver_xmlrpc="not found" else ac_cv_erlang_lib_ver_xmlrpc=`$as_echo "$ac_cv_erlang_lib_dir_xmlrpc" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_xmlrpc" >&5 $as_echo "$ac_cv_erlang_lib_ver_xmlrpc" >&6; } ERLANG_LIB_DIR_xmlrpc=$ac_cv_erlang_lib_dir_xmlrpc ERLANG_LIB_VER_xmlrpc=$ac_cv_erlang_lib_ver_xmlrpc if test "$ac_cv_erlang_lib_dir_xmlrpc" = "not found"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"xmlrpc\" Erlang application not found. It could be required to run Yaws or its testsuites." >&5 $as_echo "$as_me: WARNING: \"xmlrpc\" Erlang application not found. It could be required to run Yaws or its testsuites." >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'inets' library subdirectory" >&5 $as_echo_n "checking for Erlang/OTP 'inets' library subdirectory... " >&6; } if ${ac_cv_erlang_lib_dir_inets+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> ReturnValue = case code:lib_dir("inets") of {error, bad_name} -> file:write_file("conftest.out", "not found\n"), 1; LibDir -> file:write_file("conftest.out", LibDir), 0 end, halt(ReturnValue) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : ac_cv_erlang_lib_dir_inets=`cat conftest.out` rm -f conftest.out else if test ! -f conftest.out; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "test Erlang program execution failed See \`config.log' for more details" "$LINENO" 5; } else ac_cv_erlang_lib_dir_inets="not found" rm -f conftest.out fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_inets" >&5 $as_echo "$ac_cv_erlang_lib_dir_inets" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'inets' library version" >&5 $as_echo_n "checking for Erlang/OTP 'inets' library version... " >&6; } if ${ac_cv_erlang_lib_ver_inets+:} false; then : $as_echo_n "(cached) " >&6 else if test "$ac_cv_erlang_lib_dir_inets" = "not found"; then : ac_cv_erlang_lib_ver_inets="not found" else ac_cv_erlang_lib_ver_inets=`$as_echo "$ac_cv_erlang_lib_dir_inets" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'` fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_inets" >&5 $as_echo "$ac_cv_erlang_lib_ver_inets" >&6; } ERLANG_LIB_DIR_inets=$ac_cv_erlang_lib_dir_inets ERLANG_LIB_VER_inets=$ac_cv_erlang_lib_ver_inets if test "$ac_cv_erlang_lib_dir_inets" = "not found"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"xmlrpc\" Erlang application not found. It could be required to run Yaws or its testsuites." >&5 $as_echo "$as_me: WARNING: \"xmlrpc\" Erlang application not found. It could be required to run Yaws or its testsuites." >&2;} fi cross_compiling=$tmp_cross_compiling echo text=`$ECHO $seo "%BCheck platform-specific and system requirements%b" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec "%BCheck platform-specific and system requirements%b" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the build and host architectures" >&5 $as_echo_n "checking for the build and host architectures... " >&6; } case "$host_os" in *cygwin*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: windows (native)" >&5 $as_echo "windows (native)" >&6; } CYGWIN=true # Extract the first word of "werl", so it can be a program name with args. set dummy werl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_WERL+:} false; then : $as_echo_n "(cached) " >&6 else case $WERL in [\\/]* | ?:[\\/]*) ac_cv_path_WERL="$WERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_WERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi WERL=$ac_cv_path_WERL if test -n "$WERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WERL" >&5 $as_echo "$WERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; mingw|mingw32*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: windows (cross-compiled)" >&5 $as_echo "windows (cross-compiled)" >&6; } MINGW=true # Extract the first word of "werl", so it can be a program name with args. set dummy werl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_WERL+:} false; then : $as_echo_n "(cached) " >&6 else case $WERL in [\\/]* | ?:[\\/]*) ac_cv_path_WERL="$WERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_WERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi WERL=$ac_cv_path_WERL if test -n "$WERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WERL" >&5 $as_echo "$WERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $host_os" >&5 $as_echo "$host_os" >&6; } EPAM_CFLAGS= if test "x$enable_pam" != "xno"; then for ac_header in security/pam_appl.h pam/pam_appl.h pam_appl.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF break fi done if test "x$ac_cv_header_security_pam_appl_h" = "xyes" ; then EPAM_CFLAGS="-I/usr/include/security" elif test "x$ac_cv_header_pam_pam_appl_h" = "xyes" ; then EPAM_CFLAGS="-I/usr/include/pam" elif test "x$ac_cv_header_pam_appl_h" = "xno" ; then as_fn_error $? "\"Could not find pam_appl.h required for pam authentication\"" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_start in -lpam" >&5 $as_echo_n "checking for pam_start in -lpam... " >&6; } if ${ac_cv_lib_pam_pam_start+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pam_start (); int main () { return pam_start (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pam_pam_start=yes else ac_cv_lib_pam_pam_start=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_start" >&5 $as_echo "$ac_cv_lib_pam_pam_start" >&6; } if test "x$ac_cv_lib_pam_pam_start" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPAM 1 _ACEOF LIBS="-lpam $LIBS" else as_fn_error $? "\"Could not find pam library\"" "$LINENO" 5 fi fi ;; esac if test "x$CYGWIN" = "xtrue"; then CYGWIN_TRUE= CYGWIN_FALSE='#' else CYGWIN_TRUE='#' CYGWIN_FALSE= fi if test "x$MINGW" = "xtrue"; then MINGW_TRUE= MINGW_FALSE='#' else MINGW_TRUE='#' MINGW_FALSE= fi if test "x$MINGW" = "xtrue" -o "x$CYGWIN" = "xtrue"; then WINDOWS_TRUE= WINDOWS_FALSE='#' else WINDOWS_TRUE='#' WINDOWS_FALSE= fi HAVE_SENDFILE=false HAVE_ERLANG_SENDFILE=false if test "$WINDOWS" = true; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sendfile" >&5 $as_echo_n "checking for sendfile... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sendfile in -lc" >&5 $as_echo_n "checking for sendfile in -lc... " >&6; } if ${ac_cv_lib_c_sendfile+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sendfile (); int main () { return sendfile (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_sendfile=yes else ac_cv_lib_c_sendfile=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_sendfile" >&5 $as_echo "$ac_cv_lib_c_sendfile" >&6; } if test "x$ac_cv_lib_c_sendfile" = xyes; then : HAVE_SENDFILE=true fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file:sendfile/5" >&5 $as_echo_n "checking for file:sendfile/5... " >&6; } file_sendfile=`"${ERL}" -noshell -eval 'code:ensure_loaded(file), io:format("~p~n",[erlang:function_exported(file,sendfile,5)]), erlang:halt().' | tail -1` if test "$file_sendfile" = true; then # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. ax_compare_version_A=`echo "${ERLANG_ERTS_VER}" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version_B=`echo "5.9.1" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version=`echo "x$ax_compare_version_A x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` if test "$ax_compare_version" = "true" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_ERLANG_SENDFILE=true else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$HAVE_SENDFILE" = "xtrue"; then HAVE_SENDFILE_TRUE= HAVE_SENDFILE_FALSE='#' else HAVE_SENDFILE_TRUE='#' HAVE_SENDFILE_FALSE= fi if test "x$HAVE_ERLANG_SENDFILE" = "xtrue"; then HAVE_ERLANG_SENDFILE_TRUE= HAVE_ERLANG_SENDFILE_FALSE='#' else HAVE_ERLANG_SENDFILE_TRUE='#' HAVE_ERLANG_SENDFILE_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypto:hash/2" >&5 $as_echo_n "checking for crypto:hash/2... " >&6; } HAVE_CRYPTO_HASH=false crypto_hash=`"${ERL}" -noshell -eval 'code:ensure_loaded(crypto), io:format("~p~n",[erlang:function_exported(crypto,hash,2)]), erlang:halt().' | tail -1` if test "$crypto_hash" = true; then HAVE_CRYPTO_HASH=true { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$HAVE_CRYPTO_HASH" = "xtrue"; then HAVE_CRYPTO_HASH_TRUE= HAVE_CRYPTO_HASH_FALSE='#' else HAVE_CRYPTO_HASH_TRUE='#' HAVE_CRYPTO_HASH_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet:parse_strict_address/1" >&5 $as_echo_n "checking for inet:parse_strict_address/1... " >&6; } HAVE_INET_PARSE_STRICT_ADDRESS=false inet_parse_strict_address=`"${ERL}" -noshell -eval 'code:ensure_loaded(inet), io:format("~p~n",[erlang:function_exported(inet, parse_strict_address,1)]), erlang:halt().' | tail -1` if test "$inet_parse_strict_address" = true; then HAVE_INET_PARSE_STRICT_ADDRESS=true { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$INET_PARSE_STRICT_ADDRESS" = "xtrue"; then HAVE_INET_PARSE_STRICT_ADDRESS_TRUE= HAVE_INET_PARSE_STRICT_ADDRESS_FALSE='#' else HAVE_INET_PARSE_STRICT_ADDRESS_TRUE='#' HAVE_INET_PARSE_STRICT_ADDRESS_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erlang:now/0" >&5 $as_echo_n "checking for erlang:now/0... " >&6; } # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. ax_compare_version_A=`echo "${ERLANG_ERTS_VER}" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version_B=`echo "7.0" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version=`echo "x$ax_compare_version_A x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/false/;s/x${ax_compare_version_B}/true/;1q"` if test "$ax_compare_version" = "true" ; then have_erlang_now="yes" else have_erlang_now="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_erlang_now}" >&5 $as_echo "${have_erlang_now}" >&6; } HAVE_ERLANG_NOW=false if test "x${have_erlang_now}" = "xyes"; then HAVE_ERLANG_NOW=true fi if test "x$HAVE_ERLANG_NOW" = "xtrue"; then HAVE_ERLANG_NOW_TRUE= HAVE_ERLANG_NOW_FALSE='#' else HAVE_ERLANG_NOW_TRUE='#' HAVE_ERLANG_NOW_FALSE= fi echo text=`$ECHO $seo "%BCheck programs support%b" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec "%BCheck programs support%b" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 # Extract the first word of "latex", so it can be a program name with args. set dummy latex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DVILATEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DVILATEX"; then ac_cv_prog_DVILATEX="$DVILATEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DVILATEX="latex" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DVILATEX=$ac_cv_prog_DVILATEX if test -n "$DVILATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DVILATEX" >&5 $as_echo "$DVILATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "dvips", so it can be a program name with args. set dummy dvips; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DVIPS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DVIPS"; then ac_cv_prog_DVIPS="$DVIPS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DVIPS="dvips" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DVIPS=$ac_cv_prog_DVIPS if test -n "$DVIPS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DVIPS" >&5 $as_echo "$DVIPS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "pdflatex", so it can be a program name with args. set dummy pdflatex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PDFLATEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PDFLATEX"; then ac_cv_prog_PDFLATEX="$PDFLATEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PDFLATEX="pdflatex" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PDFLATEX=$ac_cv_prog_PDFLATEX if test -n "$PDFLATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PDFLATEX" >&5 $as_echo "$PDFLATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "epstopdf", so it can be a program name with args. set dummy epstopdf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_EPSTOPDF+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$EPSTOPDF"; then ac_cv_prog_EPSTOPDF="$EPSTOPDF" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_EPSTOPDF="epstopdf" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi EPSTOPDF=$ac_cv_prog_EPSTOPDF if test -n "$EPSTOPDF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EPSTOPDF" >&5 $as_echo "$EPSTOPDF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "man", so it can be a program name with args. set dummy man; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MAN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MAN"; then ac_cv_prog_MAN="$MAN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MAN="man" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MAN=$ac_cv_prog_MAN if test -n "$MAN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAN" >&5 $as_echo "$MAN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "ps2pdf", so it can be a program name with args. set dummy ps2pdf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PS2PDF+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PS2PDF"; then ac_cv_prog_PS2PDF="$PS2PDF" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PS2PDF="ps2pdf" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PS2PDF=$ac_cv_prog_PS2PDF if test -n "$PS2PDF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PS2PDF" >&5 $as_echo "$PS2PDF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$DVILATEX" != "x" && test "x$DVIPS" != "x" && test "x$PDFLATEX" != "x" && test "x$EPSTOPDF" != "x"; then CAN_BUILD_DOC_TRUE= CAN_BUILD_DOC_FALSE='#' else CAN_BUILD_DOC_TRUE='#' CAN_BUILD_DOC_FALSE= fi # Extract the first word of "cadaver", so it can be a program name with args. set dummy cadaver; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CADAVER+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CADAVER"; then ac_cv_prog_CADAVER="$CADAVER" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CADAVER="cadaver" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CADAVER=$ac_cv_prog_CADAVER if test -n "$CADAVER"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CADAVER" >&5 $as_echo "$CADAVER" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "curl", so it can be a program name with args. set dummy curl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CURL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CURL"; then ac_cv_prog_CURL="$CURL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CURL="curl" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CURL=$ac_cv_prog_CURL if test -n "$CURL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CURL" >&5 $as_echo "$CURL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "unix2dos", so it can be a program name with args. set dummy unix2dos; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_UNIX2DOS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$UNIX2DOS"; then ac_cv_prog_UNIX2DOS="$UNIX2DOS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_UNIX2DOS="unix2dos" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi UNIX2DOS=$ac_cv_prog_UNIX2DOS if test -n "$UNIX2DOS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $UNIX2DOS" >&5 $as_echo "$UNIX2DOS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "todos", so it can be a program name with args. set dummy todos; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_TODOS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$TODOS"; then ac_cv_prog_TODOS="$TODOS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_TODOS="todos" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi TODOS=$ac_cv_prog_TODOS if test -n "$TODOS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TODOS" >&5 $as_echo "$TODOS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x${INSTALL_BUILDER}" = "x"; then INSTALL_BUILDER="${HOME}/installbuilder-5.4.14" fi if test "x${confdir}" = "x"; then confdir='$(sysconfdir)/yaws' fi if test "x${wwwdir}" = "x"; then wwwdir='$(localstatedir)/yaws/www' fi if test "x${appsdir}" = "x"; then appsdir='$(localstatedir)/yaws' fi if test "x${logdir}" = "x"; then logdir='$(localstatedir)/log/yaws' fi if test "x${yawsdir}" = "x"; then yawsdir='$(libdir)/yaws' else ERLANG_INSTALL_LIB_DIR_yaws='${yawsdir}' fi if test "x${yappdir}" = "x"; then yappdir='$(libdir)/yapp' else ERLANG_INSTALL_LIB_DIR_yapp='${yappdir}' fi CONFIG_STATUS_DEPENDENCIES='$(top_srcdir)/vsn.mk $(top_srcdir)/applications/yapp/vsn.mk' ac_config_files="$ac_config_files yaws.pc Makefile c_src/Makefile win32/Makefile win32/build.xml man/Makefile doc/Makefile scripts/Makefile src/Makefile ebin/Makefile examples/src/Makefile examples/ebin/Makefile examples/include/Makefile www/code/Makefile www/shoppingcart/Makefile test/Makefile test/src/Makefile test/eunit/Makefile test/t1/Makefile test/t2/Makefile test/t3/Makefile test/t4/Makefile test/t5/Makefile test/t6/Makefile test/t7/Makefile test/t8/Makefile test/t9/Makefile test/t10/Makefile test/t11/Makefile test/t12/Makefile test/t13/Makefile test/t14/Makefile applications/chat/Makefile applications/chat/src/Makefile applications/chat/ebin/Makefile applications/mail/Makefile applications/mail/src/Makefile applications/mail/ebin/Makefile applications/wiki/Makefile applications/wiki/src/Makefile applications/wiki/ebin/Makefile applications/yapp/Makefile applications/yapp/src/Makefile applications/yapp/ebin/Makefile src/yaws_charset.hrl src/yaws_appdeps.hrl test/eunit//subconfig_DATA/yaws_absolute.conf test/eunit//subconfig_DATA/yaws_absolute_no_wildcard.conf test/eunit//subconfig_DATA/global_absolute_subconfig.conf test/eunit//subconfig_DATA/global_absolute_no_wildcard_subconfig.conf test/support/yaws.conf test/t1/yaws.conf test/t2/yaws.conf test/t3/yaws.conf test/t4/yaws.conf test/t5/yaws.conf test/t6/no_docroot_appmod.conf test/t6/no_docroot_fwdproxy.conf test/t6/no_docroot_redirect.conf test/t6/no_docroot_revproxy.conf test/t7/yaws.conf test/t8/yaws.conf test/t9/yaws.conf test/t10/yaws.conf test/t11/yaws.conf test/t12/yaws.conf test/t13/yaws.conf test/t14/yaws.conf" ac_config_files="$ac_config_files scripts/make-release" ac_config_files="$ac_config_files applications/wiki/scripts/addFile" ac_config_files="$ac_config_files applications/wiki/scripts/getPassword" ac_config_files="$ac_config_files applications/wiki/scripts/importFiles" ac_config_files="$ac_config_files applications/wiki/scripts/updateWiki" ac_config_files="$ac_config_files include/Makefile" ac_config_files="$ac_config_files priv/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_EPAM_TRUE}" && test -z "${WITH_EPAM_FALSE}"; then as_fn_error $? "conditional \"WITH_EPAM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_BAD_UNICODE_TRUE}" && test -z "${HAVE_BAD_UNICODE_FALSE}"; then as_fn_error $? "conditional \"HAVE_BAD_UNICODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_BAD_WILDCARD_TRUE}" && test -z "${HAVE_BAD_WILDCARD_FALSE}"; then as_fn_error $? "conditional \"HAVE_BAD_WILDCARD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SSL_HONOR_CIPHER_ORDER_TRUE}" && test -z "${HAVE_SSL_HONOR_CIPHER_ORDER_FALSE}"; then as_fn_error $? "conditional \"HAVE_SSL_HONOR_CIPHER_ORDER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SSL_CLIENT_RENEGOTIATION_TRUE}" && test -z "${HAVE_SSL_CLIENT_RENEGOTIATION_FALSE}"; then as_fn_error $? "conditional \"HAVE_SSL_CLIENT_RENEGOTIATION\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SSL_LOG_ALERT_TRUE}" && test -z "${HAVE_SSL_LOG_ALERT_FALSE}"; then as_fn_error $? "conditional \"HAVE_SSL_LOG_ALERT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CYGWIN_TRUE}" && test -z "${CYGWIN_FALSE}"; then as_fn_error $? "conditional \"CYGWIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MINGW_TRUE}" && test -z "${MINGW_FALSE}"; then as_fn_error $? "conditional \"MINGW\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WINDOWS_TRUE}" && test -z "${WINDOWS_FALSE}"; then as_fn_error $? "conditional \"WINDOWS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SENDFILE_TRUE}" && test -z "${HAVE_SENDFILE_FALSE}"; then as_fn_error $? "conditional \"HAVE_SENDFILE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_ERLANG_SENDFILE_TRUE}" && test -z "${HAVE_ERLANG_SENDFILE_FALSE}"; then as_fn_error $? "conditional \"HAVE_ERLANG_SENDFILE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_CRYPTO_HASH_TRUE}" && test -z "${HAVE_CRYPTO_HASH_FALSE}"; then as_fn_error $? "conditional \"HAVE_CRYPTO_HASH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_INET_PARSE_STRICT_ADDRESS_TRUE}" && test -z "${HAVE_INET_PARSE_STRICT_ADDRESS_FALSE}"; then as_fn_error $? "conditional \"HAVE_INET_PARSE_STRICT_ADDRESS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_ERLANG_NOW_TRUE}" && test -z "${HAVE_ERLANG_NOW_FALSE}"; then as_fn_error $? "conditional \"HAVE_ERLANG_NOW\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CAN_BUILD_DOC_TRUE}" && test -z "${CAN_BUILD_DOC_FALSE}"; then as_fn_error $? "conditional \"CAN_BUILD_DOC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by yaws $as_me 2.0.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ yaws config.status 2.0.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SED \ GREP \ EGREP \ FGREP \ SHELL \ ECHO \ LD \ PATH_SEPARATOR \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "yaws.pc") CONFIG_FILES="$CONFIG_FILES yaws.pc" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "c_src/Makefile") CONFIG_FILES="$CONFIG_FILES c_src/Makefile" ;; "win32/Makefile") CONFIG_FILES="$CONFIG_FILES win32/Makefile" ;; "win32/build.xml") CONFIG_FILES="$CONFIG_FILES win32/build.xml" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "ebin/Makefile") CONFIG_FILES="$CONFIG_FILES ebin/Makefile" ;; "examples/src/Makefile") CONFIG_FILES="$CONFIG_FILES examples/src/Makefile" ;; "examples/ebin/Makefile") CONFIG_FILES="$CONFIG_FILES examples/ebin/Makefile" ;; "examples/include/Makefile") CONFIG_FILES="$CONFIG_FILES examples/include/Makefile" ;; "www/code/Makefile") CONFIG_FILES="$CONFIG_FILES www/code/Makefile" ;; "www/shoppingcart/Makefile") CONFIG_FILES="$CONFIG_FILES www/shoppingcart/Makefile" ;; "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; "test/src/Makefile") CONFIG_FILES="$CONFIG_FILES test/src/Makefile" ;; "test/eunit/Makefile") CONFIG_FILES="$CONFIG_FILES test/eunit/Makefile" ;; "test/t1/Makefile") CONFIG_FILES="$CONFIG_FILES test/t1/Makefile" ;; "test/t2/Makefile") CONFIG_FILES="$CONFIG_FILES test/t2/Makefile" ;; "test/t3/Makefile") CONFIG_FILES="$CONFIG_FILES test/t3/Makefile" ;; "test/t4/Makefile") CONFIG_FILES="$CONFIG_FILES test/t4/Makefile" ;; "test/t5/Makefile") CONFIG_FILES="$CONFIG_FILES test/t5/Makefile" ;; "test/t6/Makefile") CONFIG_FILES="$CONFIG_FILES test/t6/Makefile" ;; "test/t7/Makefile") CONFIG_FILES="$CONFIG_FILES test/t7/Makefile" ;; "test/t8/Makefile") CONFIG_FILES="$CONFIG_FILES test/t8/Makefile" ;; "test/t9/Makefile") CONFIG_FILES="$CONFIG_FILES test/t9/Makefile" ;; "test/t10/Makefile") CONFIG_FILES="$CONFIG_FILES test/t10/Makefile" ;; "test/t11/Makefile") CONFIG_FILES="$CONFIG_FILES test/t11/Makefile" ;; "test/t12/Makefile") CONFIG_FILES="$CONFIG_FILES test/t12/Makefile" ;; "test/t13/Makefile") CONFIG_FILES="$CONFIG_FILES test/t13/Makefile" ;; "test/t14/Makefile") CONFIG_FILES="$CONFIG_FILES test/t14/Makefile" ;; "applications/chat/Makefile") CONFIG_FILES="$CONFIG_FILES applications/chat/Makefile" ;; "applications/chat/src/Makefile") CONFIG_FILES="$CONFIG_FILES applications/chat/src/Makefile" ;; "applications/chat/ebin/Makefile") CONFIG_FILES="$CONFIG_FILES applications/chat/ebin/Makefile" ;; "applications/mail/Makefile") CONFIG_FILES="$CONFIG_FILES applications/mail/Makefile" ;; "applications/mail/src/Makefile") CONFIG_FILES="$CONFIG_FILES applications/mail/src/Makefile" ;; "applications/mail/ebin/Makefile") CONFIG_FILES="$CONFIG_FILES applications/mail/ebin/Makefile" ;; "applications/wiki/Makefile") CONFIG_FILES="$CONFIG_FILES applications/wiki/Makefile" ;; "applications/wiki/src/Makefile") CONFIG_FILES="$CONFIG_FILES applications/wiki/src/Makefile" ;; "applications/wiki/ebin/Makefile") CONFIG_FILES="$CONFIG_FILES applications/wiki/ebin/Makefile" ;; "applications/yapp/Makefile") CONFIG_FILES="$CONFIG_FILES applications/yapp/Makefile" ;; "applications/yapp/src/Makefile") CONFIG_FILES="$CONFIG_FILES applications/yapp/src/Makefile" ;; "applications/yapp/ebin/Makefile") CONFIG_FILES="$CONFIG_FILES applications/yapp/ebin/Makefile" ;; "src/yaws_charset.hrl") CONFIG_FILES="$CONFIG_FILES src/yaws_charset.hrl" ;; "src/yaws_appdeps.hrl") CONFIG_FILES="$CONFIG_FILES src/yaws_appdeps.hrl" ;; "test/eunit//subconfig_DATA/yaws_absolute.conf") CONFIG_FILES="$CONFIG_FILES test/eunit//subconfig_DATA/yaws_absolute.conf" ;; "test/eunit//subconfig_DATA/yaws_absolute_no_wildcard.conf") CONFIG_FILES="$CONFIG_FILES test/eunit//subconfig_DATA/yaws_absolute_no_wildcard.conf" ;; "test/eunit//subconfig_DATA/global_absolute_subconfig.conf") CONFIG_FILES="$CONFIG_FILES test/eunit//subconfig_DATA/global_absolute_subconfig.conf" ;; "test/eunit//subconfig_DATA/global_absolute_no_wildcard_subconfig.conf") CONFIG_FILES="$CONFIG_FILES test/eunit//subconfig_DATA/global_absolute_no_wildcard_subconfig.conf" ;; "test/support/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/support/yaws.conf" ;; "test/t1/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t1/yaws.conf" ;; "test/t2/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t2/yaws.conf" ;; "test/t3/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t3/yaws.conf" ;; "test/t4/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t4/yaws.conf" ;; "test/t5/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t5/yaws.conf" ;; "test/t6/no_docroot_appmod.conf") CONFIG_FILES="$CONFIG_FILES test/t6/no_docroot_appmod.conf" ;; "test/t6/no_docroot_fwdproxy.conf") CONFIG_FILES="$CONFIG_FILES test/t6/no_docroot_fwdproxy.conf" ;; "test/t6/no_docroot_redirect.conf") CONFIG_FILES="$CONFIG_FILES test/t6/no_docroot_redirect.conf" ;; "test/t6/no_docroot_revproxy.conf") CONFIG_FILES="$CONFIG_FILES test/t6/no_docroot_revproxy.conf" ;; "test/t7/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t7/yaws.conf" ;; "test/t8/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t8/yaws.conf" ;; "test/t9/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t9/yaws.conf" ;; "test/t10/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t10/yaws.conf" ;; "test/t11/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t11/yaws.conf" ;; "test/t12/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t12/yaws.conf" ;; "test/t13/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t13/yaws.conf" ;; "test/t14/yaws.conf") CONFIG_FILES="$CONFIG_FILES test/t14/yaws.conf" ;; "scripts/make-release") CONFIG_FILES="$CONFIG_FILES scripts/make-release" ;; "applications/wiki/scripts/addFile") CONFIG_FILES="$CONFIG_FILES applications/wiki/scripts/addFile" ;; "applications/wiki/scripts/getPassword") CONFIG_FILES="$CONFIG_FILES applications/wiki/scripts/getPassword" ;; "applications/wiki/scripts/importFiles") CONFIG_FILES="$CONFIG_FILES applications/wiki/scripts/importFiles" ;; "applications/wiki/scripts/updateWiki") CONFIG_FILES="$CONFIG_FILES applications/wiki/scripts/updateWiki" ;; "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; "priv/Makefile") CONFIG_FILES="$CONFIG_FILES priv/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' <conf$$subs.awk | sed ' /^[^""]/{ N s/\n// } ' >>$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; "scripts/make-release":F) chmod +x scripts/make-release ;; "applications/wiki/scripts/addFile":F) chmod +x applications/wiki/scripts/addFile ;; "applications/wiki/scripts/getPassword":F) chmod +x applications/wiki/scripts/getPassword ;; "applications/wiki/scripts/importFiles":F) chmod +x applications/wiki/scripts/importFiles ;; "applications/wiki/scripts/updateWiki":F) chmod +x applications/wiki/scripts/updateWiki ;; "include/Makefile":F) if test -e include/yaws.hrl; then : else ln -s ${ac_abs_srcdir}/yaws.hrl include/yaws.hrl fi if test -e include/yaws_api.hrl; then : else ln -s ${ac_abs_srcdir}/yaws_api.hrl include/yaws_api.hrl fi ;; "priv/Makefile":F) if test -e priv/mime.types; then : else ln -s ${ac_abs_srcdir}/mime.types priv/mime.types fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi echo text=`$ECHO $seo " %B== ${PACKAGE_NAME} ${PACKAGE_VERSION} ==%b" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %B== ${PACKAGE_NAME} ${PACKAGE_VERSION} ==%b" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 echo text=`$ECHO $seo "Configuration:" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec "Configuration:" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %BApplication dir.%b: ${ERLANG_INSTALL_LIB_DIR_yaws}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %BApplication dir.%b: ${ERLANG_INSTALL_LIB_DIR_yaws}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 echo text=`$ECHO $seo " %BPrefix%b: ${prefix}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %BPrefix%b: ${prefix}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %Betcdir%b: ${sysconfdir}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %Betcdir%b: ${sysconfdir}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %Bconfdir%b: ${confdir}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %Bconfdir%b: ${confdir}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %Bbindir%b: ${bindir}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %Bbindir%b: ${bindir}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %Bvardir%b: ${localstatedir}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %Bvardir%b: ${localstatedir}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %Bwwwdir%b: ${wwwdir}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %Bwwwdir%b: ${wwwdir}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %Bappsdir%b: ${appsdir}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %Bappsdir%b: ${appsdir}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %Blogdir%b: ${logdir}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %Blogdir%b: ${logdir}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %Byawsdir%b: ${yawsdir}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %Byawsdir%b: ${yawsdir}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %Bdocdir%b: ${docdir}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %Bdocdir%b: ${docdir}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %Bmandir%b: ${mandir}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %Bmandir%b: ${mandir}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 echo text=`$ECHO $seo " %BErlang root dir%b: ${ERLANG_ROOT_DIR}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %BErlang root dir%b: ${ERLANG_ROOT_DIR}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %BErlang lib dir%b: ${ERLANG_LIB_DIR}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %BErlang lib dir%b: ${ERLANG_LIB_DIR}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %BErlang compiler%b: ${ERLC}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %BErlang compiler%b: ${ERLC}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %BErlang emulator%b: ${ERL}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %BErlang emulator%b: ${ERL}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 text=`$ECHO $seo " %BWindows Erlang emulator%b: ${WERL}" | sed -e "s/%B/${colored_echo_bold}/g" -e "s/%b/${colored_echo_norm}/g" 2>/dev/null` $ECHO $seo "$text" text=`$ECHO $sec " %BWindows Erlang emulator%b: ${WERL}" | sed -e "s/%B//g" -e "s/%b//g" 2>/dev/null` $as_echo "$as_me:${as_lineno-$LINENO}: $text" >&5 echo ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/Makefile.am������������������������������������������������������������������������������0000664�0001750�0001750�00000014306�12605311412�011454� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ACLOCAL_FLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src ebin include priv APPDIRS = applications/chat applications/mail applications/wiki applications/yapp if !WINDOWS # don't c-compile anything on win32 (yet) # I don't know how to make a linked in driver using gcc, or any other compiler # there, and have no intentions of finding out SUBDIRS += c_src endif if MINGW SUBDIRS += win32 endif SUBDIRS += examples/src examples/ebin examples/include \ test doc man scripts www/code www/shoppingcart EXTRA_DIST = ChangeLog known_dialyzer_warnings LICENSE \ README.md README.osx README.pkg-config \ rebar.config rebar.config.script two-mode-mode.el vsn.mk \ include.mk erlang_deps.mk ssl munin contrib www rel if !MINGW pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = yaws.pc endif all-local: clean-local: $(AM_V_at)rm -f dialyzer_warnings install-data-local: all $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(wwwdir) $(AM_V_at)(cd @top_srcdir@; tar cf - www ) | (cd $(DESTDIR)$(wwwdir)/..; tar xf - ) $(AM_V_at)chmod -R u+rw $(DESTDIR)$(wwwdir) $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(logdir) $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(sysconfdir)/yaws $(AM_V_at)$(INSTALL) -m 644 @srcdir@/ssl/yaws-cert.pem $(DESTDIR)$(sysconfdir)/yaws $(AM_V_at)$(INSTALL) -m 644 @srcdir@/ssl/yaws-key.pem $(DESTDIR)$(sysconfdir)/yaws $(AM_V_at)$(INSTALL) -m 644 @srcdir@/ssl/dhparams.pem $(DESTDIR)$(sysconfdir)/yaws @echo "-------------------------------" @echo @echo "** etc files went into $(sysconfdir)" @echo "** executables went into $(bindir)" @echo "** library files went into $(ERLANG_INSTALL_LIB_DIR_yaws)" @echo "** logs went into $(logdir)" @echo "** doc files went into $(docdir)" @echo "** man files went into $(mandir)" @echo "** default docroot went into $(wwwdir)" $(AM_V_at)if test $(yawsdir) != $(ERLANG_INSTALL_LIB_DIR_yaws); then \ echo; \ if test -d $(DESTDIR)$(yawsdir) && test ! -h $(DESTDIR)$(yawsdir); then \ backupdir="$(DESTDIR)$(yawsdir).backup"; \ echo "backup old yaws directory into $${backupdir}"; \ mv $(DESTDIR)$(yawsdir) $${backupdir}; \ else \ $(INSTALL) -d `dirname $(yawsdir)`; \ rm -f $(DESTDIR)$(yawsdir); \ fi; \ $(LN_S) -f $(ERLANG_INSTALL_LIB_DIR_yaws) $(DESTDIR)$(yawsdir); \ echo "create link $(ERLANG_INSTALL_LIB_DIR_yaws) -> $(yawsdir)"; \ fi @echo @echo "--------------------------------" uninstall-local: $(AM_V_at)(cd @top_srcdir@/www && find * -type f -exec rm -f $(DESTDIR)$(wwwdir)/{} \;) $(AM_V_at)(cd @top_srcdir@/www && find * -type d -exec rm -fr $(DESTDIR)$(wwwdir)/{} \;) $(AM_V_at)[ ! -h $(yawsdir) ] || rm -f $(DESTDIR)$(libdir)/yaws $(AM_V_at)rm -r $(DESTDIR)$(sysconfdir)/yaws/yaws-cert.pem $(AM_V_at)rm -r $(DESTDIR)$(sysconfdir)/yaws/yaws-key.pem $(AM_V_at)rm -r $(DESTDIR)$(sysconfdir)/yaws/dhparams.pem debug: $(MAKE) DEBUG_ERLC_FLAGS=" -Ddebug" CFLAGS="-Werror -Wall -O0 -g" docs: doc doc: $(AM_V_at)( cd doc && $(MAKE) doc ) test: check cleantest: $(AM_V_at)( cd test && $(MAKE) clean ) yaws.plt: $(AM_V_GEN)dialyzer --build_plt -r ebin --output_plt yaws.plt \ -r $(ERLANG_LIB_DIR_kernel) \ -r $(ERLANG_LIB_DIR_stdlib) \ -r $(ERLANG_LIB_DIR_sasl) \ -r $(ERLANG_LIB_DIR_erts) \ -r $(ERLANG_LIB_DIR_compiler) \ -r $(ERLANG_LIB_DIR_crypto) \ -r $(ERLANG_LIB_DIR_xmerl) dialyzer: all yaws.plt $(AM_V_at)$(DIALYZER) -q --plt yaws.plt -r ebin > dialyzer_warnings || true $(AM_V_at)if diff -U0 @srcdir@/known_dialyzer_warnings dialyzer_warnings ; then \ echo dialyzer check passed ; \ exit 0 ; \ else \ exit 1 ; \ fi dist-hook: $(AM_V_at)for a in $(APPDIRS); do \ $(INSTALL) -d $(distdir)/$$a; \ (cd $$a && $(MAKE) top_distdir=../../$(distdir) \ distdir=../../$(distdir)/$$a distdir); \ done find $(distdir) -type d -name .deps | xargs rm -rf distclean-local: $(AM_V_at)[ ! -h include/yaws.hrl ] || rm -f include/yaws.hrl $(AM_V_at)[ ! -h include/yaws_api.hrl ] || rm -f include/yaws_api.hrl $(AM_V_at)[ ! -h priv/mime.types ] || rm -f priv/mime.types $(AM_V_at)for a in $(APPDIRS); do \ (cd $$a && $(MAKE) distclean); \ done mkinstaller: cleaninstaller $(AM_V_at)if [ -z "$(UNIX2DOS)" -a -z "$(TODOS)" ]; then \ echo "No unix2dos/todos program found"; \ echo "Run apt-get install dos2unix/tofrodos"; \ exit 1; \ fi $(AM_V_at)if [ ! -d "$(INSTALL_BUILDER)" ]; then \ echo "No installer-builder found"; \ echo "For more information, read win32/README.developer"; \ exit 1; \ fi $(AM_V_at)$(MAKE) distdir $(AM_V_at)$(MKDIR_P) $(distdir)/_build $(AM_V_at)(cd $(distdir)/_build && ../configure \ --host i586-mingw32msvc --prefix=/ --docdir=/doc --mandir=/man \ wwwdir=/www logdir=/logs yawsdir=/ confdir=/ appsdir=/applications \ yappdir=/applications/yapp INSTALL_BUILDER=$(INSTALL_BUILDER)) $(AM_V_at)(cd $(distdir)/_build && $(MAKE) install DESTDIR=@abs_builddir@/$(distdir)/_inst) $(AM_V_at)(cd $(distdir)/_build && $(MAKE) installapps DESTDIR=@abs_builddir@/$(distdir)/_inst) $(AM_V_at)(cd $(distdir)/_build/win32 && $(MAKE) mkinstaller DESTDIR=@abs_builddir@/$(distdir)/_inst) $(AM_V_at)cp $(distdir)/*.exe @builddir@ $(AM_V_at)rm -fr $(distdir) cleaninstaller: $(AM_V_at)rm -f *.exe $(AM_V_at)rm -fr $(distdir) apps: $(APPDIRS) $(APPDIRS): $(AM_V_at)(cd $@ && $(MAKE) all) cleanapps: $(AM_V_at)for a in $(APPDIRS); do \ (cd $$a && $(MAKE) clean); \ done installapps: apps $(AM_V_at)$(INSTALL) -d $(DESTDIR)$(appsdir) $(AM_V_at)for a in $(APPDIRS); do \ (cd $$a && $(MAKE) install); \ done uninstallapps: apps $(AM_V_at)for a in $(APPDIRS); do \ (cd $$a && $(MAKE) uninstall); \ done fullinstall: install installapps fulluninstall: uninstall uninstallapps fullclean: clean cleantest cleaninstaller cleanapps .PHONY: test doc $(APPDIRS) # Local Variables: # tab-width: 8 # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yaws-2.0.2/ChangeLog��������������������������������������������������������������������������������0000664�0001750�0001750�00000431023�12605311412�011171� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������2007-02-08 16:38 klacke * configure: need to also check in configure after the setuod_drv gcc/ld patch 2007-02-06 17:25 klacke * src/yaws_cgi.erl: added auth env stuff to yaws_cgi patch by Julian Noble 2007-02-06 12:04 etnt * src/yaws_server.erl: Bugfix by Magnus Froberg: binding socket with fd_server now only listens to the specified IP address given in #sconf.listen 2007-02-04 17:38 klacke * ChangeLog, www/code.yaws, www/news, www/setpcookie.yaws, www/upload.yaws: preparing for 1.67 2007-02-04 16:56 klacke * vsn.mk: preparing for release 1.67 2007-02-04 16:47 klacke * src/yaws_server.erl: Removed the urlc_total counter - it didn't provide info which was worth the proce of having it - Also Chris NewCombe reported trobles with the counter 2007-02-02 10:28 etnt * src/Makefile: Added install of the priv/*.xsd files 2007-02-01 16:58 etnt * src/yaws_api.erl: Fixing yaws_api:find_cookie_val/2 which was broken. 2007-01-30 11:27 etnt * www/soap_intro.yaws: Added paragraph with some limitation regarding binding style and type of encoding. 2007-01-26 16:55 etnt * www/soap_intro.yaws: Made the examples look prettier. 2007-01-26 15:53 etnt * www/soap_intro.yaws: Adding missing description on call to: yaws_soap_srv:setup/2. 2007-01-24 08:49 klacke * src/yaws_config.erl: patch from Dimitriy Kargapolov for tmpdir handling 2007-01-23 15:46 etnt * src/yaws_soap_lib.erl: Bugfix by Feredrik Thulin: The (undocumented) http_uri:parse/1 return format was changed between Erlang/OTP R11B-1 and R11B-2. 2007-01-19 21:43 klacke * configure.in: [no log message] 2007-01-19 21:42 klacke * src/yaws.erl: Patch from Fredrik Thulin to make setuid_drv work better under ubuntu where gcc with some stack smashing tech is used to build, then we cannot use ld, we need to use ggc to greate the shared object 2007-01-19 10:17 etnt * src/yaws_server.erl: Appmod </, Mod> didn't work properly. Should be fixed now. 2007-01-17 10:43 etnt * src/yaws_rss.erl: The generated content was not valid RSS 2.0 content. This is fixed now. 2007-01-02 23:58 klacke * doc/yaws.tex, man/yaws.conf.5, src/yaws_config.erl: added ability to have config files in several files, patch from Sergei Golovan 2006-12-29 19:27 etnt * src/yaws_rpc.erl, www/json_intro.yaws: Added call to callback function: M:F(cookie_expire) which is expected to return a proper cookie expire string. If non-existant, the default behaviour will prevail, i.e a session bases cookie lifetime. 2006-12-25 16:45 etnt * src/yaws_api.erl: Extending yaws_api:find_cookie_val/2 to accept an #arg record as second argument as well. 2006-12-22 04:10 yarivvv * www/haxe_intro.yaws: tweaked the haXe documentation 2006-12-17 21:02 klacke * www/: news, soap_intro.yaws: vsn 1.66 2006-12-17 19:23 klacke * applications/mail/src/Makefile: [no log message] 2006-12-16 16:12 mikaelka * applications/yapp/Makefile: Fix to yapp Makefile to clean all generated files in doc directory 2006-12-14 23:45 etnt * src/yaws.erl: Adding add_server/2 and lots of access functions for manipuling the #ssl{} record 2006-12-13 09:30 etnt * www/doc.yaws: Adding entry for the yaws_soap_lib man-page. 2006-12-12 17:43 etnt * man/: yaws.conf.5, yaws_soap_lib.5: Adding a new man page for the yaws_soap_lib module. Also, added enable_soap config to yaws.conf.5 2006-12-12 17:25 etnt * src/yaws_soap_lib.erl: [no log message] 2006-12-12 17:13 etnt * src/yaws_soap_lib.erl: [no log message] 2006-12-12 16:46 etnt * src/yaws_soap_lib.erl: [no log message] 2006-12-12 16:42 etnt * src/yaws_soap_lib.erl: Adding yaws_soap_lib:call/4 which takes the acual Header and Body messages. 2006-12-12 15:24 etnt * src/yaws_soap_lib.erl: [no log message] 2006-12-12 15:20 etnt * src/yaws.erl: Fixing the setup of the PAM/Auth stuff when starting embedded Yaws. 2006-12-12 14:49 etnt * src/yaws_soap_lib.erl: Fixing the handling of the return value from the http-request. 2006-12-12 13:32 klacke * src/yaws_cgi.erl: override cgienv if provideded env in extraenv 2006-12-12 10:54 klacke * ChangeLog, www/news: [no log message] 2006-12-12 10:47 klacke * vsn.mk: preparing for 1.66 2006-12-12 10:33 klacke * scripts/yaws.template: [no log message] 2006-12-12 10:29 klacke * src/yaws.erl: need pam for embedded mode 2006-12-12 00:54 klacke * src/yaws.erl, www/json_sample.yaws: small bug fixes 2006-12-11 17:20 klacke * c_src/epam.c: set RUSER so that pam_group.so works for us 2006-12-10 23:32 etnt * include/erlsom.hrl, include/soap.hrl, include/yaws.hrl, priv/envelope.xsd, priv/soap.xsd, priv/wsdl.xsd, src/Makefile, src/yaws.erl, src/yaws_config.erl, src/yaws_rpc.erl, src/yaws_soap_lib.erl, src/yaws_soap_srv.erl, www/TAB.inc, www/json_intro.yaws, www/soap_intro.yaws: Adding SOAP processing capabilities to Yaws. Read the www/soap_intro.yaws for more info. 2006-12-10 20:55 klacke * scripts/Install, scripts/Makefile, scripts/make-upload, src/Makefile: Make/build fixes 2006-12-06 00:05 klacke * src/yaws_config.erl: bug found in path handling for yaws_dir by CEAN guys 2006-12-01 22:15 klacke * src/yaws_compile.erl: handle compiler crash 2006-11-28 21:48 klacke * src/yaws_server.erl: filer econnreset errors 2006-11-27 20:29 klacke * src/yaws_api.erl: memory better htmlize 2006-11-20 23:20 klacke * src/yaws_server.erl: shutdown fixes from Danile Luna 2006-11-19 23:14 klacke * src/yaws_cgi.erl: added env DOCUMENT_ROOT to cgi env vars - Michael FIG 2006-11-19 18:09 klacke * src/yaws_server.erl: dont log write errors when error is 'closed' 2006-11-09 21:30 etnt * src/yaws_server.erl: Fixed bug: the 'start_mod' module was not called correctly when having several servers listening to the same port. 2006-11-06 23:41 klacke * src/yaws_server.erl: the pathinfo elem in #arg got wrong when appmod was / 2006-11-05 22:20 klacke * src/yaws.erl: start_embedded default flags patch by Jason Andersson 2006-10-18 16:18 jbevemyr * src/: yaws_log.erl, yaws_server.erl: Fixed logging for authmodule 2006-10-18 15:51 jbevemyr * include/yaws.hrl, man/yaws.conf.5, src/yaws_config.erl, src/yaws_server.erl: Added option for having a module for handling authentication. 2006-10-09 22:44 mikaelka * applications/yapp/src/yapp.erl: Fix to yapp for starting dependencies, patch from Michael Leonhard 2006-09-20 14:34 klacke * man/yaws_api.5, src/yaws_api.erl: [no log message] 2006-09-20 09:46 klacke * www/: arg.yaws, arg2.yaws: added the client IP address to the #arg record 2006-09-20 09:29 klacke * include/yaws_api.hrl, src/yaws_server.erl: added the client IP address to the #arg record 2006-09-19 09:41 klacke * include/yaws.hrl, man/yaws.conf.5, src/yaws_config.erl, src/yaws_server.erl: added config flag 'use_large_ssl_pool = bool()' 2006-09-11 20:12 klacke * ChangeLog, vsn.mk, www/news: preparing for 1.65 2006-09-11 11:11 klacke * src/yaws_server.erl: patch by Chris NewCombeto handle PUT method better 2006-09-10 23:23 klacke * www/configuration.yaws: [no log message] 2006-09-09 22:48 mikaelka * www/yapp_intro.yaws: Fixed some formulations 2006-09-09 19:42 mikaelka * www/: TAB.inc, yapp_intro.yaws: added yapp_intro.yaws 2006-09-09 19:40 mikaelka * applications/yapp/src/yapp.erl: fix so that files in top directory that start with same string as the yapp are not affected 2006-09-08 21:47 yarivvv * src/haxe.erl: removed debug logging statements 2006-09-08 20:07 yarivvv * src/haxe.erl: Updated the haXe remoting adapter to be compatible with the latest version of haXe. The main improvement is the performance of the caching algorithm 2006-09-07 16:28 etnt * src/yaws.erl: Bugfix of my stupidity 2006-09-07 16:10 etnt * src/yaws.erl: Fixed a typo in start_embedded/N. 2006-09-06 13:22 etnt * src/ymnesia.erl: Added the ymnesia.erl appmod. 2006-09-06 10:05 klacke * src/yaws_zlib.erl: patch from Matthew Reilley to handle new return value from OTP zlib:deflate/4 2006-09-05 22:14 etnt * src/yaws.erl, www/embed.yaws: Reworked the start_embedded functions into three functions. start_embedded(DocRoot). start_embedded(DocRoot, SC_KeyValueList). start_embedded(DocRoot, SC_KeyValueList, GC_KeyValueList). 2006-09-05 16:58 klacke * src/yaws_compile.erl: [no log message] 2006-09-05 15:53 etnt * src/yaws.erl: Added start_embedded/2 that takes a list of sconf attributes. 2006-09-05 10:10 etnt * www/embed.yaws: [no log message] 2006-09-05 10:07 etnt * www/embed.yaws: Updated to reflect the yaws:start_embedded/N functions. 2006-09-05 09:09 etnt * src/: yaws_jsonrpc.erl, yaws_rpc.erl, yaws_xmlrpc.erl: Corrected reference to yaws_api.hrl so that they now compile properly. 2006-09-05 08:56 etnt * src/yaws.erl: Added start_embedded/1 and start_embedded/4. Quick and easy way of starting Yaws in embedded mode. No need for any start-script switches and no dependencies to Yaws header files. Just call either start_embedded/1 or start_embedded/4 and you are in the air. 2006-09-03 17:41 mikaelka * applications/yapp/: Makefile, README, vsn.mk, doc/.empty, ebin/.empty, priv/docroot/END.inc, priv/docroot/HEAD.inc, priv/docroot/add.yaws, priv/docroot/add_post.yaws, priv/docroot/index.yaws, priv/docroot/list.yaws, priv/docroot/remove.yaws, priv/docroot/remove_post.yaws, src/Makefile, src/yapp.app.src, src/yapp.erl, src/yapp_app.erl, src/yapp_event_handler.erl, src/yapp_handler.erl, src/yapp_mnesia_server.erl, src/yapp_registry.erl, src/yapp_server.erl, src/yapp_sup.erl: added Yaws application handler - yapp 2006-09-03 17:34 mikaelka * src/yaws_server.erl: Added dynamic Docroot to ssi for Yapps 2006-08-30 09:13 klacke * src/yaws_server.erl: patch from anders nygren to handle absolute paths + yssi 2006-08-28 20:53 klacke * scripts/yaws.template, src/json.erl, src/yaws_compile.erl, src/yaws_ctl.erl: patch from Magnus froberg to get better control over the files generated by 'yaws --check'. This is good if one wants to run i.e. xref and dialyzer also on all the generated .erl files from the --checker 2006-08-25 16:46 klacke * src/: mime_type_c.erl, yaws_api.erl, yaws_dav.erl, yaws_server.erl: found errors with xref 2006-08-23 09:38 klacke * src/json.erl: empty array bug in json parse found by juhani and fixed by gaspar 2006-08-07 12:20 klacke * src/yaws_server.erl: [no log message] 2006-08-07 12:19 klacke * src/yaws_server.erl: appmod '/' was broken 2006-08-07 11:35 klacke * scripts/: Install, netbsd/yaws.sh: NetBSD support from Kuzma Bartosz 2006-07-13 13:09 klacke * ChangeLog, www/news: [no log message] 2006-07-13 13:06 klacke * vsn.mk: preparing for 1.64 2006-07-13 10:42 jbevemyr * applications/mail/src/smtp.erl: Fixes from Bengt Kleberg to make smtp.erl useful outside the webmail app. 2006-07-06 11:04 klacke * src/: Makefile, yaws_cgi.erl, yaws_ctl.erl: patch by Sergei Golovan which fixed a CGI bug and made yaws_ctl safe 2006-07-03 11:17 klacke * scripts/: Install, darwin/Yaws.StartupItem: install patches for macosX by Eric Baur 2006-06-27 22:26 yarivvv * www/haxe_intro.yaws: fix documentation typo 2006-06-27 06:47 yarivvv * www/haxe_sample.yaws: fixed documentation bug in haxe_sample.yaws 2006-06-27 06:29 yarivvv * www/: haxe_intro.yaws, haxe_intro.yaws: fixed documentation bug in haxe_intro.yaws 2006-06-27 06:10 yarivvv * src/Makefile, src/haxe.erl, src/yaws_rpc.erl, www/haxe_intro.yaws, www/haxe_sample.html, www/json_intro.yaws, www/TAB.inc, www/json_sample.yaws: Added a haXe remoting adapter with documentation 2006-06-22 12:30 klacke * src/yaws_server.erl: made index.php autoload if it exists 2006-06-19 11:00 klacke * www/json_intro.yaws: [no log message] 2006-06-16 14:50 klacke * scripts/debian/yaws.init.d: [no log message] 2006-06-16 14:38 klacke * scripts/: Install, debian/yaws.init.d: added debian startup script 2006-06-16 14:25 klacke * c_src/Makefile: [no log message] 2006-06-16 14:21 klacke * README: [no log message] 2006-06-15 14:44 klacke * www/shopingcart/shopcart.erl: [no log message] 2006-06-11 16:51 klacke * vsn.mk, www/news: tiny followup rel 2006-06-11 16:47 klacke * scripts/: Install, Makefile: weird make behaviour from macos make 2006-06-07 23:09 klacke * Makefile: [no log message] 2006-06-07 22:35 klacke * Makefile, src/yaws.erl, src/yaws_server.erl, src/yaws_sup.erl, www/news: mikl hup fixes 2006-06-07 22:13 klacke * ChangeLog, www/internals.yaws, www/news: [no log message] 2006-06-07 22:07 klacke * Makefile, configure, configure.in, vsn.mk, src/Makefile, src/yaws_config.erl, src/yaws_generated.template: preparing for 1.62 2006-06-01 09:15 klacke * include/yaws.hrl, man/yaws.conf.5: changed default php exe to php-cgi 2006-05-31 15:09 klacke * scripts/yaws.template: [no log message] 2006-05-31 00:11 klacke * configure, configure.in, include.mk.in, scripts/Install, scripts/Makefile: [no log message] 2006-05-30 23:31 klacke * src/Makefile, src/json.erl, src/jsonrpc.erl, src/yaws_jsonrpc.erl, src/yaws_xmlrpc.erl, www/TAB.inc, www/json_intro.yaws, www/json_sample.html, www/json_sample.yaws, www/jsolait/jsolait.js, www/jsolait/lib/jsonrpc.js, www/jsolait/lib/urllib.js: JSON ajax code from Gaspar Chilingarov, I added docs describing an example 2006-05-30 17:20 klacke * include.mk.in, doc/Makefile, scripts/Install, scripts/yaws.template, src/yaws_config.erl, src/yaws_ctl.erl: run_erl to_erl support patch from Mats Cronquist 2006-04-28 17:42 klacke * src/yaws_ctl.erl: [no log message] 2006-04-28 17:35 klacke * src/: yaws_content_negotiation.erl, yaws_server.erl, yaws_zlib.erl: some bugs in non used code found by dialyzer 2006-04-27 22:02 klacke * scripts/gentoo/conf.d.yaws, scripts/gentoo/init.d.yaws, www/news, doc/yaws.pdf: [no log message] 2006-04-27 21:47 klacke * ChangeLog, scripts/freebsd/yaws.sh, src/yaws_ctl.erl, www/news: preparing for 1.61 2006-04-27 21:38 klacke * scripts/yaws.template, src/yaws_config.erl, src/yaws_ctl.erl: [no log message] 2006-04-27 21:25 klacke * Makefile, README, configure, configure.in, include.mk.in, vsn.mk, c_src/Makefile, man/Makefile, man/yaws.1, man/yaws.conf.5, man/yaws_api.5, scripts/Install, scripts/Makefile, scripts/yaws.template, src/Makefile, src/yaws.erl, src/yaws_api.erl, src/yaws_cgi.erl, src/yaws_config.erl, src/yaws_ctl.erl, src/yaws_generated.template, www/code/Makefile, www/shopingcart/Makefile: added support for 2 additional configure flags, --disable-pam and --with-extrainclude=DIR Worked the Makefiles to properly support DESTDIR. This is useful for packagers (deb, rpm ...) 2006-04-05 09:53 klacke * src/yaws_ls.erl: [no log message] 2006-04-05 09:53 klacke * LICENSE: changed licens to proper BSD 2006-03-18 00:32 klacke * scripts/: darwin/Yaws.StartupItem, gentoo/conf.d.yaws, redhat/yaws.init.d, suse/yaws.init.d: [no log message] 2006-03-18 00:17 klacke * src/yaws_log.erl: [no log message] 2006-03-17 23:57 klacke * ChangeLog, www/news: "" 2006-03-17 23:46 klacke * vsn.mk: prearing for 1.60 2006-03-14 21:59 klacke * include.mk.in: [no log message] 2006-03-09 22:58 klacke * include/yaws.hrl, man/yaws.1, man/yaws.conf.5, scripts/yaws.template, src/Makefile, src/yaws.erl, src/yaws_404.erl, src/yaws_api.erl, src/yaws_cgi.erl, src/yaws_compile.erl, src/yaws_config.erl, src/yaws_ctl.erl, src/yaws_html.erl, src/yaws_log.erl, src/yaws_ls.erl, src/yaws_revproxy.erl, src/yaws_server.erl, src/yaws_session_server.erl, src/yaws_ssl.erl, src/yaws_sup.erl: removed the ability change userid, also stopped writing to /tmp/yaws and started to write to /home/klacke/.yaws instead. This is much better since we cannot now ever get into the situations where file ownership and umask stop us from controlling a daemon. Also cleaned up the start flags to the yaws script, all old flags are still there for backward scompatibilty. 2006-03-09 18:25 klacke * c_src/Makefile: [no log message] 2006-03-06 17:22 klacke * man/yaws.conf.5: [no log message] 2006-02-26 14:38 mbj * applications/wiki/: README, src/wiki.erl, src/wiki_format_txt.erl: Fixed error printouts; handle https and ftp links; updated READE 2006-02-22 14:40 klacke * src/yaws_ctl.erl: file descriptor leak bug found by Mats Cronqvist where each call to 'yaws -ls' left an unclosed dscriptor in the server 2006-02-21 14:08 klacke * src/yaws_ctl.erl: [no log message] 2006-02-14 23:22 klacke * c_src/Makefile, c_src/epam.c, man/yaws.conf.5, src/yaws_config.erl, src/yaws_server.erl, src/yaws_sup.erl: [no log message] 2006-02-14 22:00 klacke * ChangeLog, www/news: "" 2006-02-14 21:10 klacke * c_src/Makefile: "" 2006-02-14 20:56 klacke * c_src/epam.c, include/yaws.hrl, src/Makefile, src/mime_type_c.erl, src/yaws_config.erl, src/yaws_ctl.erl, src/yaws_ls.erl, src/yaws_server.erl, src/yaws_sup.erl: pam cleanup, add env record, yaws_ls enhancements by doccarcass@gmail.com 2006-02-12 16:59 mikaelka * src/yaws_server.erl: Clearold ets table instead of deleting and making a new one when updating sconf line 559 2006-02-07 20:25 klacke * src/yaws_revproxy.erl: broken revproxy 2006-02-07 12:14 klacke * man/yaws.conf.5: [no log message] 2006-02-03 15:01 sstrollo * configure, configure.in, c_src/epam.c: Handle pam include files in different location... 2006-02-03 14:47 sstrollo * c_src/setuid_drv.c: Call setpwent() in setuid_drv (which wasn't working without it on FreeBSD) 2006-02-01 23:43 klacke * c_src/epam.c: [no log message] 2006-02-01 23:41 klacke * c_src/Makefile: "" 2006-02-01 23:36 klacke * ChangeLog, www/news: [no log message] 2006-02-01 23:27 klacke * vsn.mk, c_src/Makefile, doc/yaws.pdf, include/yaws.hrl, man/yaws.conf.5, man/yaws_api.5, src/Makefile, src/yaws_config.erl, src/yaws_pam.erl, src/yaws_server.erl, src/yaws_sup.erl: added pam support + prepare for 1.58 2005-12-10 19:21 mikaelka * src/yaws_server.erl: changed so that an arg_rewrite_mod may temporarily change the docroot by changing the Arg#arg.docroot attribute 2005-11-30 21:10 klacke * include/yaws.hrl, man/yaws.conf.5, scripts/yaws.conf.template, src/yaws_config.erl, src/yaws_server.erl: added support for fdsrv 2005-11-25 20:49 etnt * src/: yaws_config.erl, yaws_rss.erl: Fixing the yaws-rss functionality. Adding configure parameter rss_dir, defining the directory where to store the RSS database. 2005-11-23 23:52 mbj * src/yaws.erl: fixed allow_header for non-DAV case 2005-11-23 23:45 mbj * include/yaws.hrl, src/Makefile, src/dav.erl, src/yaws.erl, src/yaws_config.erl, src/yaws_dav.erl, src/yaws_server.erl: reworked the DAV support a bit - don't use an appmod, instead yaws has built-in support for DAV methods. Added support for missing DAV methods (COPY etc). 2005-11-20 23:30 klacke * src/: yaws.erl, yaws_api.erl, yaws_cgi.erl, yaws_compile.erl, yaws_config.erl, yaws_content_negotiation.erl, yaws_ctl.erl, yaws_debug.erl, yaws_log.erl, yaws_ls.erl, yaws_revproxy.erl, yaws_server.erl, yaws_ssl.erl: "" 2005-10-11 14:12 klacke * src/mime_type_c.erl: bad charset header genererated 2005-10-05 13:24 klacke * src/yaws_server.erl: "" 2005-10-04 22:21 etnt * src/yaws_rss.erl: Cleaned up w3cdtf-date function by Daniel Kaminski. 2005-10-03 09:41 etnt * src/yaws_rss.erl: Updated the RSS date format, as suggested by Daniel Kaminski. 2005-10-03 09:34 etnt * doc/README.rss, src/yaws_rss.erl: Fixed the RSS date format, as suggested by Daniel Kaminski. 2005-09-30 11:16 klacke * src/yaws_server.erl: [no log message] 2005-09-30 11:04 klacke * include/yaws.hrl, src/yaws_config.erl, src/yaws_server.erl: "" 2005-09-29 10:03 klacke * include/yaws.hrl, man/yaws.conf.5, scripts/yaws.conf.template, src/yaws_config.erl, src/yaws_server.erl: added feature to not pick first sconf when virthosting 2005-09-28 17:31 klacke * man/yaws.conf.5: "" 2005-09-25 16:51 mikl * applications/wiki/wiki.conf: Fixed path to the application directory where yaws files are stored. 2005-09-16 14:45 etnt * doc/README.rss: Updated RSS documentation. 2005-09-16 14:41 etnt * src/yaws_rss.erl: Made month and days in RSS output to consist of two figures instead of just one. 2005-09-13 16:11 klacke * src/mime.types: "" 2005-08-17 15:08 klacke * ChangeLog, src/Makefile, src/yaws_revproxy.erl, www/news: "" 2005-08-17 15:01 klacke * vsn.mk: preparing for 1.57 2005-08-17 01:01 klacke * include/yaws.hrl: rel/abs path patch by Rob Schmersel which fixed a problem in the wiki 2005-08-15 20:26 klacke * src/: yaws_revproxy.erl, yaws_ssl.erl: "" 2005-08-15 17:45 klacke * src/: yaws.erl, yaws_ctl.erl, yaws_debug.erl, yaws_revproxy.erl, yaws_server.erl, yaws_ssl.erl: rewrote yaws SSL code to use the packet http and packet line modes that are now supported in the OTP ssl module. Earlier this was all manual (and slow) code in yaws. Thus yaws/SSL servers are now considerably faster 2005-08-15 13:01 klacke * src/: yaws_server.erl, yaws_session_server.erl, yaws_ssl.erl: support chunked data from the client 2005-07-05 11:08 klacke * src/: yaws.erl, yaws_server.erl: tmp patch by Karel Ostrovsky 2005-07-02 16:30 klacke * src/yaws_cgi.erl: cgi port patch by joe_e_e 2005-07-02 16:17 mikl * ChangeLog, src/yaws_cgi.erl: yaws_cgi.erl: Do not send the server port along with the host name in the CGI HTTP_HOST environment variable. 2005-06-30 15:40 mikl * ChangeLog, src/yaws_cgi.erl: Added HTTP_HOST env variable for CGI scripts (was required by sphpblog). 2005-06-30 15:37 mikl * ChangeLog, include.mk.in: Added compile option to generate debug information in the Erlang beam file 2005-06-17 12:58 klacke * www/: dynamic.yaws, index.yaws, news: "" 2005-06-16 13:59 klacke * www/news, www/yaws-1.55_to_1.56.patch, vsn.mk: "" 2005-06-16 13:47 klacke * www/news: "" 2005-06-16 13:36 klacke * src/yaws_api.erl: "" 2005-06-16 13:33 klacke * src/yaws_api.erl: "" 2005-06-10 16:17 klacke * ChangeLog, www/news: "" 2005-06-10 16:08 klacke * vsn.mk: preparing for release 1.55 2005-06-08 14:58 klacke * include/yaws.hrl, man/yaws.conf.5, src/yaws_config.erl, src/yaws_server.erl: added the possibilty to have multiple docroots, where a page is searched in the list of docroots 2005-06-07 20:08 klacke * scripts/Install: "" 2005-06-07 13:13 klacke * man/yaws.1, scripts/yaws.template: -erlarg patch by Fredrik Thulin 2005-05-26 22:54 etnt * src/yaws_dav.erl: [no log message] 2005-05-23 19:14 klacke * man/yaws_api.5: "" 2005-05-20 00:47 etnt * src/: dav.erl, yaws_server.erl: Adding support for PUT and DELETE. 2005-05-19 20:21 etnt * src/dav.erl: [no log message] 2005-05-19 00:36 etnt * src/dav.erl: [no log message] 2005-05-18 16:42 klacke * scripts/yaws.template: "" 2005-05-18 00:12 etnt * src/: Makefile, dav.erl: Begun work with providing a filsystem dav appmod. 2005-05-17 10:37 etnt * src/yaws_dav.erl: Fixed include file references. 2005-05-16 23:24 etnt * src/: yaws.erl, yaws_server.erl: Adding the MKCOL method (webdav). 2005-05-16 23:12 etnt * src/yaws_api.erl: Added return code 207, Multi Status 2005-05-16 14:56 etnt * src/yaws_dav.erl: [no log message] 2005-05-16 13:58 etnt * include/yaws_dav.hrl, src/Makefile, src/yaws.erl, src/yaws_dav.erl, src/yaws_server.erl: Adding the beginning of WebDav support. The PROPFIND method has been added. The intention is to let appmods take care of the WebDav specfics. 2005-05-16 13:01 klacke * src/yaws_api.erl: "" 2005-05-12 15:12 klacke * doc/yaws.tex, scripts/Makefile, www/code/Makefile, www/shopingcart/Makefile: "" 2005-04-29 14:28 mikl * src/yaws.erl: temp directory is now taken from TMP environment variable, and a default is used if the environment variable is not set 2005-04-25 15:48 klacke * src/: yaws_config.erl, yaws_server.erl: new feature called redirect maps whereby its possible to redir entire parts of the docroot to another site 2005-04-25 13:54 klacke * src/yaws_server.erl: Removed the forbidden code, the right thing to do when a scripttype is forbidden and we shall not run an interpreter on the script is to ship the script, but as text/plain instead of actually refusing to ship the data. Otherwise it's not possible to publish .php files at all on the website. 2005-04-18 22:55 jbevemyr * include/yaws.hrl, man/yaws.conf.5, src/yaws_config.erl, src/yaws_server.erl: Added redirect map 2005-04-18 22:33 jbevemyr * applications/mail/src/mail.erl: Fixed various bugs and removed pre_html. 2005-04-12 15:44 klacke * ChangeLog, man/yaws_api.5, www/internals.yaws, www/news, www/stil.css: 1.54 2005-04-12 14:49 klacke * vsn.mk: prepare for 1.54 2005-04-12 14:48 klacke * src/: yaws_config.erl, yaws_debug.erl, yaws_revproxy.erl, yaws_server.erl, yaws_sup.erl: better looking debug printouts + dont overwrite trace_to_tty (-x commandline) if set on the commandline and ind the config file, commandline should have precedense 2005-04-12 13:30 klacke * doc/yaws.pdf, include/yaws.hrl, src/yaws_server.erl, www/internals.yaws, www/redirect.yaws: Bug fixed with bindings that got propagated over redirects. Good ol get/put bug 2005-04-12 09:35 klacke * src/yaws_content_negotiation.erl: "" 2005-04-11 15:59 klacke * www/: TAB.inc, compile_layout.dia, compile_layout.png, internals.yaws, process_tree.dia, process_tree.png: "" 2005-04-10 18:34 mikl * src/yaws_revproxy.erl: By default proxy is not keep-alived 2005-04-10 14:42 mikl * src/: yaws_api.erl, yaws_revproxy.erl: Fixed yaws_proxy bugs (client request was sent twice, Cookie header was always added, tuple use as PID). I still need to do some refactoring 2005-03-29 22:52 klacke * src/yaws.erl: buggy printout of server URI during startup 2005-03-23 21:04 klacke * src/yaws.erl: "" 2005-03-22 00:56 klacke * src/yaws_compile.erl, www/appmods.yaws, www/configuration.yaws, www/dynamic.yaws, www/post.yaws, www/ssi.yaws, www/stream.yaws, www/yman.yaws: added possibility to name the module in a .yaws file 2005-03-15 00:32 cschultz * src/yaws_server.erl: Two bug fixes, one of them serious: When clearing the cache, yaws modules would remain loaded but be forgotten, resulting in a memory leak. 2005-03-06 21:23 klacke * www/arg.yaws: "" 2005-03-04 00:59 jbevemyr * applications/chat/chat/chat.js: Fixed smilie situation in chat. 2005-03-04 00:54 jbevemyr * applications/chat/chat/: chat.js, chat.yaws: Fixed smilie situation in chat. 2005-03-03 17:00 jbevemyr * applications/chat/chat/chat.yaws: Added smileys. 2005-03-03 16:51 jbevemyr * applications/chat/chat/chat.yaws: Added smileys. 2005-03-03 16:24 jbevemyr * applications/chat/chat/: angel.png, bigsmile.png, burp.png, chat.yaws, cool.png, crossedlips.png, cry.png, embarrassed.png, farted.png, kiss.png, moneymouth.png, oneeye.png, sad.png, scream.png, smile.png, think.png, tongue.png, wink.png, yell.png: Added smileys. 2005-02-28 16:56 jbevemyr * applications/chat/: chat/chat.js, chat/chat.yaws, src/chat.erl: Improved chat server some. 2005-02-28 16:32 jbevemyr * applications/chat/: chat/chat.js, chat/chat.yaws, src/chat.erl, chat/chat.js: Improved chat server some. 2005-02-27 13:59 klacke * src/yaws_server.erl: cleaner shutdown 2005-02-25 16:32 klacke * src/yaws_api.erl: removed the automatic htmlize on strings in ehtml, it was wrong ... (I think cvslsdiff .to have it there, it's better for users that want it to explicitly add htmlize() to their strings, this breaks code and is non backwards compat Be aware. Also made {Tag, Attr} generate xhtml compliant code 2005-02-25 16:22 klacke * src/: yaws_api.erl, yaws_ssl.erl: bad line parsing in ssl mode, crashed when client sent headers splitup in a certain way 2005-02-23 22:28 klacke * src/yaws_session_server.erl: "" 2005-02-21 10:28 klacke * src/yaws_api.erl: one more url_decode bug 2005-02-18 21:15 klacke * ChangeLog, www/news: "" 2005-02-18 21:02 klacke * vsn.mk: prepare for 1.53 2005-02-18 20:57 klacke * src/yaws_server.erl: fatso bug found by Fredrik Linder where yaws completely crash on bad URLs that for example contain space chars in the uri 2005-02-17 13:56 jbevemyr * applications/wiki/src/wiki_to_html.erl: Added urlencoding to some urls that didn't have that. 2005-02-17 13:54 klacke * src/yaws_api.erl: removed urldecode utf hackery 2005-02-16 10:18 jbevemyr * applications/chat/: Makefile, include.mk, chat/chat.js, chat/chat.yaws, chat/chat_read.yaws, chat/chat_write.yaws, chat/index.yaws, chat/login.yaws, src/Makefile, src/chat.erl: Added example chat program. 2005-02-15 20:55 klacke * include/yaws.hrl, man/yaws.conf.5, scripts/yaws.conf.template, src/yaws_config.erl, src/yaws_server.erl: "" 2005-02-14 11:35 klacke * ChangeLog, www/news: "" 2005-02-14 11:29 klacke * vsn.mk: ver 1.52 prepare 2005-02-14 11:28 klacke * src/yaws_config.erl: "" 2005-02-14 11:27 klacke * src/: yaws.erl, yaws_api.erl, yaws_config.erl, yaws_ctl.erl, yaws_debug.erl, yaws_server.erl: erlang:faultify 2005-02-07 14:29 klacke * src/yaws_revproxy.erl: error condition bug in revproxy, found by Tobbe 2005-02-02 15:12 klacke * src/yaws_api.erl, src/yaws_config.erl, www/TAB.inc, www/internals.yaws: embedded bugfix by Michael Arnoldus 2005-01-26 16:20 klacke * src/yaws.erl: connection close bug found by Lennart Ostman 2005-01-25 20:56 klacke * src/yaws_server.erl: "" 2005-01-25 20:54 klacke * src/yaws_server.erl: made errorlog actually go out when conf is broke + daemon 2005-01-21 00:27 jbevemyr * applications/mail/src/mail.erl: Fixed decode problem. 2005-01-15 16:12 cschultz * src/yaws_cgi.erl: Allow to pass additional environment variables. 2004-12-29 20:25 klacke * src/: Makefile, mime_type_c.erl, yaws_server.erl: solaris make trouble reported by Petter Larsson 2004-12-21 11:05 klacke * www/stil.css: "" 2004-12-20 12:18 etnt * doc/README.rss, src/yaws_config.erl, src/yaws_rss.erl, src/yaws_sup.erl: Yaws is now RSS capable, see doc/README.rss 2004-12-20 00:39 etnt * doc/README.rss, src/yaws_config.erl, src/yaws_rss.erl: Added RSS config parameters ro config parser and some more documentation. 2004-12-18 00:29 klacke * www/stream.yaws: "" 2004-12-17 09:43 jbevemyr * applications/wiki/README: Updated the documentation some. 2004-12-17 09:40 jbevemyr * applications/wiki/wiki/WikiPreferences.files/: template2.html, template_info2.html: Added a new example look and feel for the wiki. 2004-12-16 22:12 jbevemyr * src/yaws_server.erl: Fixed problem with rel_path ssi, missing /. 2004-12-16 21:54 jbevemyr * applications/mail/: mail/login.yaws, src/mail.erl: Fixed problem with login with empty fields in FireFox. 2004-12-16 21:52 jbevemyr * applications/wiki/src/wiki.erl: Fixed minor unzip problem triggered when uploading zip archives with names containing spaces. 2004-12-16 16:13 etnt * doc/README.rss, src/Makefile, src/yaws_rss.erl: Added RSS store/interface. 2004-12-16 00:08 klacke * www/news: "" 2004-12-15 22:47 klacke * src/yaws_server.erl: "" 2004-12-15 22:25 klacke * www/news: "" 2004-12-15 22:23 klacke * ChangeLog, vsn.mk, www/news: preparing for 1.51 2004-12-15 22:17 klacke * man/yaws.conf.5, www/code.yaws: "" 2004-12-15 17:03 jbevemyr * applications/wiki/: src/wiki.erl, wiki/searchPage.yaws: Added search code from Jouni Ryno 2004-12-15 14:46 klacke * include/yaws.hrl, src/yaws.erl, src/yaws_api.erl, src/yaws_config.erl, src/yaws_log.erl, src/yaws_server.erl, www/contact.yaws: added support for config changes without stopping the running systems, virt servers can be added, removed anc changed without conflicting with traffic 2004-12-13 23:46 klacke * include/yaws.hrl, man/yaws.conf.5, scripts/yaws.conf.template, src/yaws_config.erl, src/yaws_log.erl, src/yaws_server.erl: added client IP resolv for access log files 2004-12-13 22:47 klacke * Makefile: safer make install 2004-12-11 17:32 klacke * www/code.yaws: "" 2004-12-11 17:24 klacke * src/yaws_api.erl, src/yaws_compile.erl, www/TAB.inc, www/code.yaws, www/news, www/upload.yaws, www/upload0.yaws: "" 2004-12-11 02:35 jbevemyr * applications/mail/src/mail.erl: Updated mail according to changed APIs for parse_multipart. 2004-12-11 02:29 jbevemyr * applications/wiki/src/wiki.erl: Updated wiki according to changed APIs for parse_multipart. 2004-12-11 01:48 klacke * src/Makefile: "" 2004-12-11 01:25 klacke * ChangeLog, www/index.yaws, www/news: preparing for 1.50 2004-12-10 13:30 klacke * src/yaws_compile.erl, src/yaws_server.erl, www/bindings.yaws, www/embed.yaws, www/index.yaws, www/redirect.yaws: added <verbatim> tag for .yaws files, It works as the pre (or the code) tag really should work, i.e. verbatim 2004-12-10 00:24 klacke * www/TAB.inc: "" 2004-12-10 00:21 klacke * www/: index.yaws, index.yaws: "" 2004-12-10 00:05 klacke * www/: arg.yaws, bindings.yaws, cookies.yaws, embed.yaws, form.yaws, pcookie.yaws, query.yaws, readpcookie.yaws, redirect.yaws, session.yaws, ssi.yaws, upload.yaws, upload0.yaws: more w3c compliance 2004-12-09 23:35 klacke * www/redirect4.yaws: "" 2004-12-09 01:17 klacke * www/: END, END2, TAB.inc, appmods.yaws, arg.yaws, configuration.yaws, contact.yaws, contribs.yaws, doc.yaws, dynamic.yaws, index.yaws, post.yaws, simple.yaws, ssi.yaws, stats.yaws, stil.css, upload0.yaws: "" 2004-12-02 16:13 klacke * doc/yaws.pdf, src/yaws_server.erl, www/END2, www/TAB.inc, www/appmods.yaws, www/arg.yaws, www/bindings.yaws, www/configuration.yaws, www/contact.yaws, www/contribs.yaws, www/cookies.yaws, www/doc.yaws, www/dynamic.yaws, www/embed.yaws, www/form.yaws, www/index.yaws, www/pcookie.yaws, www/query.yaws, www/redirect.yaws, www/session.yaws, www/simple.yaws, www/ssi.yaws, www/stil.css, www/stream.yaws, www/upload0.yaws: more css hackery 2004-11-26 22:33 klacke * src/yaws_server.erl, www/arg.yaws, www/configuration.yaws, www/session1.yaws, www/stil.css: "" 2004-11-26 21:16 klacke * www/: TAB.inc, END2: "" 2004-11-26 21:12 klacke * src/Makefile: "" 2004-11-19 22:58 klacke * vsn.mk, include/yaws.hrl, man/yaws.conf.5, scripts/yaws.conf.template, src/yaws_api.erl, src/yaws_config.erl, src/yaws_log.erl, src/yaws_server.erl, www/EXHEAD, www/TOPTAB, www/api.yaws, www/appmods.yaws, www/arg.yaws, www/bindings.yaws, www/code.yaws, www/configuration.yaws, www/contact.yaws, www/contribs.yaws, www/cookies.yaws, www/doc.yaws, www/dynamic.yaws, www/embed.yaws, www/form.yaws, www/index.yaws, www/man.yaws, www/pcookie.yaws, www/post.yaws, www/query.yaws, www/readpcookie.yaws, www/redirect.yaws, www/redirect2.yaws, www/redirect3.yaws, www/session.yaws, www/setpcookie.yaws, www/simple.yaws, www/simple_ex3.yaws, www/simple_ex4.yaws, www/ssi.yaws, www/stil.css, www/stream.yaws, www/upload.yaws, www/upload0.yaws, www/yman.yaws: added log_wrap_size, configurable wrap size for all logs, fixed a bug introduced by jb for ssi, major doics overhaul again, redid yaws docs using CSS only, 2004-11-09 22:24 jbevemyr * applications/mail/mail/mail.js: Fixed problem with attached files 2004-11-09 16:53 mikl * src/yaws_api.erl: Bugfix: Form post parameter was still always managed as atoms. 2004-11-08 21:38 klacke * doc/yaws.tex, man/yaws.conf.5, src/yaws_api.erl: minor docs corrections 2004-11-03 10:52 mbj * src/yaws_ls.erl: Fixed bad checkin 2004-11-02 21:46 mbj * src/Makefile: revert bad checkin 2004-11-02 21:45 mbj * include/yaws.hrl, man/yaws.conf.5, src/Makefile, src/yaws_config.erl, src/yaws_ls.erl, src/yaws_server.erl: Added auto-generate all.zip to dir listings. It needs the zip command in the current path to function properly. To turn off, use dir_listsings = true_nozip 2004-11-02 16:57 klacke * src/yaws_api.erl: infinity timeout in setconf 2004-10-12 15:30 cschultz * src/yaws.erl: typo in is_space/1. 2004-10-12 15:21 cschultz * src/yaws_ls.erl: Removed `/?N=n' etc from links for files. 2004-10-06 21:44 jbevemyr * applications/wiki/src/wiki_templates.erl: Fixed problem for non-root wikies. 2004-10-06 21:42 jbevemyr * src/yaws_server.erl: Added relative path to ssi, ie {ssi, {rel_path, File}, ...} is now possible. 2004-09-23 23:08 jbevemyr * src/: yaws_api.erl, yaws_server.erl: Fixed problem with large urlencoded posts and partial post size. 2004-09-23 23:00 jbevemyr * applications/mail/: mail/listop.yaws, mail/mail.yaws, src/mail.erl: Fixed refresh bug. 2004-09-14 12:10 klacke * src/yaws_api.erl: "" 2004-09-14 00:02 klacke * man/yaws_api.5, www/EXHEAD, www/stream.yaws, www/urandom.yaws: added example docs on how to stream data 2004-09-13 21:37 klacke * src/yaws_api.erl: modded patch by sebastian strollo to let request_url/1 and reformat_url/1 be proper inverses of each other 2004-09-10 21:49 jbevemyr * applications/wiki/src/wiki.erl: [no log message] 2004-09-09 23:40 jbevemyr * applications/wiki/src/wiki.erl: Updated template.html 2004-09-09 23:34 jbevemyr * applications/wiki/src/wiki_utils.erl: Updated template.html 2004-09-09 23:31 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_templates.erl, wiki/WikiPreferences.files/template_info.html, src/wiki_utils.erl: Updated template.html 2004-09-09 23:17 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_templates.erl, wiki/WikiPreferences.files/template.html: Updated template.html 2004-09-08 00:46 jbevemyr * applications/wiki/src/wiki_utils.erl: [no log message] 2004-09-08 00:43 jbevemyr * applications/wiki/: scripts/Makefile, scripts/addFile.src, src/wiki.erl, src/wiki_templates.erl, src/wiki_to_html.erl, wiki/WikiPreferences.wob, wiki/WikiPreferences.files/template.html, wiki/WikiPreferences.files/template_info.html: Made upgrading to new style Wiki templates smooth. If no template.html file exists in the WikiPreferences.files directory, then one is created. The same goes for template_info.html. 2004-09-03 15:07 cschultz * www/news: s/cshultz/cschultz/ :-) 2004-09-03 10:02 klacke * src/yaws_server.erl: "" 2004-09-02 22:28 klacke * www/news, src/yaws_debug.erl: "" 2004-09-02 22:00 klacke * ChangeLog: "" 2004-09-02 21:56 klacke * ChangeLog: [no log message] 2004-09-02 21:53 klacke * vsn.mk: preparing for version 1.49 2004-09-02 10:31 klacke * src/: yaws_cgi.erl, yaws_server.erl: patch from Paul Mahon to add PEER_ADDR to cgi env 2004-09-02 00:37 jbevemyr * applications/wiki/scripts/updateWiki.src: [no log message] 2004-09-02 00:27 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_templates.erl, src/wiki_utils.erl, wiki/WikiPreferences.files/template.html, wiki/WikiPreferences.files/template_info.html: Made layout of wiki much more configurable using templates and ssi. You must run the script/updateWiki script after updating to this release. 2004-09-02 00:25 jbevemyr * src/yaws_server.erl: Fixed bug in ssi code. Multichar delims were not handled properly. When a char of the delim string was found in the text it was deleted. 2004-08-29 22:46 mikl * src/yaws_api.erl: Fix htmlize bug (&quote; was used instead of &quot;) 2004-08-19 15:27 klacke * src/yaws_server.erl: "" 2004-08-16 20:57 klacke * src/yaws_api.erl: quote doubletick in htmlize 2004-08-14 19:40 cschultz * src/yaws_server.erl: Rewrite requests with absolute URI to look like requests with a Host header. 2004-08-02 20:02 klacke * www/testdir/xxåäöxx.jpg: [no log message] 2004-08-02 19:44 klacke * src/yaws.erl: bad mount number for september 2004-07-12 12:25 jbevemyr * src/yaws_api.erl: Security option for setcookie. 2004-07-12 12:07 jbevemyr * src/yaws_api.erl: Added secure option to cookie. 2004-07-11 16:44 cschultz * src/yaws_server.erl: Made process exit with stream_timeout in case of a timeout while streaming, so that these are logged. 2004-07-11 16:10 cschultz * src/yaws_server.erl: Have several processes wait for SSL connections, so that one SSL negotiation in progress does not prevent other connections. Also, for the similar reasons, have use a timeout with SSL accepts. The values for the number of processes and the duration of the timeout are quite arbitrary. They are ok for my low traffic site. 2004-07-09 17:14 klacke * src/mime.types: added mime types for svg and xhtml 2004-06-23 13:38 klacke * configure.in: [no log message] 2004-06-21 10:46 jbevemyr * applications/mail/mail/mail.js: [no log message] 2004-06-21 01:36 cschultz * src/yaws_server.erl: Do not cache a yaws file once for each value of pathinfo. Current solution: Do not use cache at all if pathinfo /= undefined. 2004-06-21 00:20 jbevemyr * applications/mail/: mail/reply.yaws, src/mail.erl, src/mail_html.erl: Added original message as quoted in reply. 2004-06-21 00:11 cschultz * src/yaws_server.erl: Bugfix: Simple typo, let a process crash after clearing the cache. 2004-06-20 16:20 cschultz * src/yaws_server.erl: fixed silly bug with content-range 2004-06-19 23:42 jbevemyr * applications/mail/src/: mail_html.erl, mail.erl: [no log message] 2004-06-19 23:38 jbevemyr * applications/mail/: mail/mail.js, mail/reply.yaws, src/Makefile, src/mail.erl: Fixed delete email bug. 2004-06-18 20:22 jbevemyr * applications/mail/src/mail.erl: Fixed 'mailbox already locked' bug 2004-06-18 15:35 cschultz * src/yaws_server.erl: Bugfix: Multiple dots in yaws file name caused trouble with pathinfo. 2004-06-18 13:42 klacke * src/yaws_revproxy.erl: "" 2004-06-17 21:05 klacke * configure, configure.in, include.mk.in, include/yaws.hrl, src/Makefile, src/mime_type_c.erl, src/yaws.erl, src/yaws_revproxy.erl, src/yaws_server.erl: addded configure option -with-defaultcharset 2004-06-17 09:25 klacke * src/yaws_server.erl: small embedded fix by Jimmy Olgeni 2004-06-16 02:28 cschultz * src/: yaws.erl, yaws_server.erl: more deflate logic 2004-06-16 01:46 cschultz * www/news: Fixed spelling of my name :-) 2004-06-16 01:03 cschultz * src/: yaws.erl, yaws_ls.erl, yaws_server.erl, yaws_zlib.erl: Deflate rehaul: Now works with dynamic pages. 2004-06-14 23:39 jbevemyr * applications/mail/src/: attachment.erl, mail.erl: [no log message] 2004-06-12 10:27 jbevemyr * applications/mail/src/: attachment.erl, mail.erl: Improved attachement handling with proper parsing of attached emails. 2004-06-11 14:33 klacke * two-mode-mode.el, scripts/ntpath.sh: two-mode.el contributed by David Welton 2004-06-10 22:23 jbevemyr * applications/mail/src/mail.erl: Fixed 'Mailbox already locked.' problem. 2004-06-09 14:10 klacke * src/yaws_api.erl: David Welton discovered that url on the form http://www.x.com?foo had yaws_api:queryval/2 return {nokey, "foo"} which is clearly wrong. New correct val is {"foo", undefined}. 2004-06-08 17:54 klacke * scripts/make-upload: "" 2004-06-08 17:35 klacke * src/Makefile: "" 2004-06-08 00:35 klacke * doc/yaws.pdf: "" 2004-06-08 00:20 klacke * vsn.mk, doc/yaws.pdf, src/yaws_server.erl, www/news, www/ssi.yaws: gearing up to 1.48 release 2004-06-08 00:12 klacke * ChangeLog: [no log message] 2004-06-07 17:59 klacke * www/upload.yaws: security vulnerability in upload.yaws founf by mbj emacs upload.yaws &emacs upload.yaws & 2004-06-07 17:50 klacke * src/yaws_server.erl: Patch from Jocke Grebeno which handles ssi support for ehtml code, not just ascii. We can now return {ssi, "@@", file.html, [{"FOO", "bar"}, {"BAZ", {ehtml, {p, [], "saab"}}}]} and it returns the expected 2004-06-07 09:15 jbevemyr * applications/: mail/src/mail.erl, wiki/src/wiki.erl: Fixed potential security problem in file upload code. 2004-06-06 23:40 jbevemyr * applications/mail/src/mail.erl: [no log message] 2004-06-04 15:15 klacke * include.mk.in, scripts/Install, scripts/Makefile, src/yaws.erl, src/yaws_revproxy.erl, src/yaws_server.erl, src/yaws_sup.erl: patch from Fredrik Linder to make it easier to integrate yaws into apps that don't use the otp application framework at all 2004-06-01 11:26 jbevemyr * applications/mail/src/mail.erl: Fixed POP server interop problem. 2004-05-28 15:56 klacke * man/yaws_api.5, src/yaws_api.erl, src/yaws_session_server.erl: yaws_session_server ttl patch from Rob.Schmersel 2004-05-28 15:24 klacke * man/yaws_api.5, src/yaws_server.erl: New feature yssi, yaws include 2004-05-28 13:38 klacke * include/yaws.hrl, src/yaws.erl, src/yaws_config.erl, src/yaws_server.erl: MOved phpexe config variable from the sconf to the gconf, it doesn't make sence to have different phpexe paths for different virt servers 2004-05-28 12:55 klacke * src/: yaws.erl, yaws_api.erl: make appmods into tuples when loaded as list of strings in setconf, the {pathelem, mod} thing actually broke old code that loadedconf with yaws_api:setconf/2 and using appmods 2004-05-27 15:17 klacke * src/: yaws.erl, yaws_api.erl, yaws_ctl.erl, yaws_server.erl: Bug in yaws_api:request_url/1 with explicit portnums in URLs found by Einar Karttunen 2004-05-27 14:40 klacke * ChangeLog, vsn.mk, www/news: 1.47 2004-05-27 14:36 klacke * src/yaws_server.erl: "" 2004-05-26 23:26 klacke * www/: appmods.yaws, bindings.yaws, news, todo.yaws: "" 2004-05-26 23:21 klacke * src/: Makefile, yaws_log.erl: "" 2004-05-26 23:00 klacke * src/yaws_config.erl: "" 2004-05-26 22:49 klacke * scripts/Makefile: "" 2004-05-26 22:45 klacke * scripts/Makefile: "" 2004-05-26 13:26 klacke * src/yaws_ctl.erl: "" 2004-05-26 13:16 klacke * man/yaws.1, scripts/yaws.template, src/yaws_ctl.erl: added a 'yaws -ls' command that lists all yaws servers on localhost 2004-05-25 18:04 klacke * c_src/setuid_drv.c, src/yaws.erl, src/yaws_ctl.erl: "" 2004-05-25 16:10 klacke * scripts/yaws.conf.template, src/yaws_server.erl: patch from Jimmy Olgeni to handle embedded mode better, no ctl process is started for an embedded node 2004-05-25 15:53 klacke * vsn.mk, src/yaws_log.erl: don't create logs when we're using nolog 2004-05-25 13:47 klacke * src/yaws_server.erl: "" 2004-05-25 13:26 klacke * Makefile, src/yaws_server.erl, www/EXHEAD, www/appmods.yaws, www/code/Makefile, www/code/myappmod.erl: documented appmods as an example 2004-05-25 10:40 klacke * include/yaws.hrl, src/yaws.erl, src/yaws_config.erl, src/yaws_server.erl: Rewrote url splitting (again), and made the redir to index.{html,yaws} go away, it was a bad decision to redir to index.yaws when it exists and the url doesn't contain it, also reworked appmods a bit 2004-05-24 15:37 klacke * include.mk.in, debian/rules, scripts/Install, scripts/Makefile, scripts/yaws.conf, src/Makefile: debian patch from David Welton applied 2004-05-12 15:59 klacke * www/ybed.erl: [no log message] 2004-04-23 16:07 jbevemyr * src/yaws_config.erl: Fixed appmod problem. 2004-04-22 22:40 mbj * src/yaws_ls.erl: use the same file list sort in subdirs as in parent dir 2004-04-22 21:55 mbj * src/: yaws_log.erl, yaws_server.erl: added username from authorization header to access log 2004-04-22 19:53 jbevemyr * applications/mail/src/mail.erl: Fixed mail delete bug. 2004-04-16 00:02 klacke * www/: news, news: "" 2004-04-15 23:54 klacke * src/: yaws_server.erl, yaws_server.erl: "" 2004-04-15 23:48 klacke * src/yaws_config.erl: "" 2004-04-15 23:41 klacke * vsn.mk: "" 2004-04-15 23:41 klacke * man/yaws.conf.5, src/yaws_config.erl, src/yaws_server.erl: new appmod config syntax and ~user bug fixes 2004-04-06 14:31 klacke * src/yaws.erl: "" 2004-04-02 15:44 jbevemyr * applications/mail/src/mail.erl: Fixed attachement reading bug in webmail. 2004-04-02 00:20 jbevemyr * applications/wiki/src/wiki.erl: [no log message] 2004-03-31 23:27 jbevemyr * src/yaws_server.erl: Removed debug printout. 2004-03-31 23:24 jbevemyr * applications/wiki/src/wiki.erl: Added support for uploading multiple files in one go. 2004-03-30 20:49 jbevemyr * applications/mail/src/mail.erl: Fixed error message in webmail. 2004-03-27 16:45 cschultz * src/yaws_server.erl: Fixed previous fix, sorry. Will have to clean this up later... 2004-03-25 14:28 jbevemyr * applications/mail/src/mail.erl: Fixed problem with error messages in webmail. 2004-03-23 00:39 cschultz * src/yaws_server.erl: Bug fix: Large posts and SSL. (NB yaws:cli_recv may return less data than requested.) (plus an unrelated code cleanup) 2004-03-22 16:54 klacke * scripts/yaws.template: "" 2004-03-22 15:08 klacke * src/yaws_ctl.erl: "" 2004-03-22 14:56 klacke * scripts/yaws.template, src/yaws_ctl.erl: "" 2004-03-22 14:45 klacke * src/yaws_ctl.erl: "" 2004-03-22 02:03 cschultz * src/yaws.erl: Bug fix: We cannot keep the connection alive if we are dynamically compressing the content (and therfore do not know its length in advance) and cannot use chunked transfer. 2004-03-21 22:49 jbevemyr * applications/mail/src/mail.erl: Fixed delete of email problem introduced in yaws rewrite. 2004-03-21 21:30 klacke * TODO, vsn.mk, scripts/yaws.template, src/yaws_server.erl, www/favicon.ico, scripts/yaws.template: "" 2004-03-21 06:04 lpsmith * src/yaws_ls.erl: Fixed XSS vulnerability 2004-03-20 23:08 jbevemyr * applications/wiki/src/wiki.erl: Fixed spelling error which resulted in javascript error in wiki. 2004-03-20 23:03 jbevemyr * src/yaws_server.erl: Fixed completely broken get_more_post_data. Probably cleanup gone bad :-) 2004-03-20 20:24 jbevemyr * applications/wiki/src/: wiki.erl, wiki_yaws.erl: Fixed bug introduced by change of query format. 2004-03-20 20:24 jbevemyr * src/yaws_server.erl: Fixed multipart bug. 2004-03-20 09:43 jbevemyr * applications/mail/src/mail.erl: Fixed sorting problem for webmail 2004-03-19 15:35 klacke * src/yaws_config.erl: "" 2004-03-19 13:56 cschultz * src/yaws.erl: Bug fix in uid_change_files. 2004-03-19 10:50 cschultz * src/yaws_ls.erl: trivial CSS fix 2004-03-18 17:26 klacke * src/yaws_server.erl: [no log message] 2004-03-18 16:04 klacke * src/yaws_server.erl: cgi bug 2004-03-18 15:43 klacke * www/shopingcart/shopcart.erl: [no log message] 2004-03-18 15:33 klacke * www/news: [no log message] 2004-03-18 15:28 klacke * ChangeLog, vsn.mk, src/yaws_api.erl, src/yaws_server.erl, www/news: "" 2004-03-18 14:45 klacke * src/yaws_config.erl: "" 2004-03-18 14:31 klacke * Makefile, README, man/yaws.conf.5, scripts/Install, scripts/Makefile, scripts/Subst, scripts/mangle, scripts/yaws.conf.basic_auth, scripts/yaws.conf.template, scripts/yaws.conf.template.local, scripts/yaws.ss, scripts/yaws.template, src/Makefile, src/yaws_config.erl, src/yaws_server.erl, ssl/cert.example, ssl/key.example, ssl/yaws-cert.pem, ssl/yaws-key.pem: New better install procedure, better (more interesting) yaws.conf template generated 2004-03-17 17:01 klacke * src/yaws.erl, src/yaws_api.erl, src/yaws_config.erl, src/yaws_debug.erl, src/yaws_server.erl, www/code.yaws, www/dynamic.yaws, www/form.yaws, www/post.yaws: some more debug support 2004-03-17 12:40 klacke * src/: yaws.erl, yaws_server.erl: more beautiful http/traffic tracing 2004-03-17 12:33 jbevemyr * applications/mail/src/mail.erl: Fixed problem with encoded attachements. 2004-03-16 17:40 klacke * src/: yaws.erl, yaws_config.erl, yaws_server.erl: better support for old netscape browser, keep-alive 2004-03-16 13:19 klacke * applications/mail/mail/headers.yaws, applications/mail/mail/listop.yaws, applications/mail/mail/login.yaws, applications/mail/mail/mail.yaws, applications/mail/mail/reply.yaws, applications/mail/mail/showmail.yaws, applications/mail/src/attachment.erl, applications/wiki/src/wiki.erl, include/yaws.hrl, include/yaws_api.hrl, man/yaws.conf.5, src/yaws.erl, src/yaws_404.erl, src/yaws_api.erl, src/yaws_compile.erl, src/yaws_config.erl, src/yaws_ctl.erl, src/yaws_debug.erl, src/yaws_ls.erl, src/yaws_revproxy.erl, src/yaws_server.erl, src/yaws_ssl.erl, www/index.yaws, www/man.yaws, www/post.yaws, www/query.yaws, www/shopingcart/shopcart.erl: Removed the atoms in parse_post and parse query, backwards incompatible change updateed wiki and mail for this, added a backwards_compat_flag to gconf put gconf and sconf in the dictionary as opposed to passing them around as args reworked url_type so there are no more flat lists, removed the list_to_atom call for the spec cache. 2004-03-14 23:53 jbevemyr * applications/mail/: TODO, mail/down.gif, mail/mail.yaws, mail/up.gif, src/mail.erl: Added sorting capability to webmail. You can now sort/reverse sort on mail nr, sender, subject, date and size. 2004-03-13 12:02 klacke * config.guess, config.sub, include/yaws_api.hrl, src/yaws_server.erl, www/index.yaws: "" 2004-03-12 21:09 klacke * www/icons/yaws_y.gif: "" 2004-03-12 00:09 klacke * include/yaws.hrl, man/yaws.conf.5, src/Makefile, src/yaws.erl, src/yaws_api.erl, src/yaws_config.erl, src/yaws_debug.erl, src/yaws_log.erl, src/yaws_log_file_h.erl, src/yaws_revproxy.erl, src/yaws_server.erl, www/todo.yaws: backwards incomp cahnge with flags in gc and sc instead of many bools, chunk bugs in revproxy, possibility to not copy the error_log, workaround buggy error_logger_file_h which doesn't append when you reopen a file, now we have the report files kept over restarts 2004-03-11 11:22 klacke * man/yaws_api.5, src/yaws.erl, src/yaws_api.erl: explicit support for content_length 2004-03-11 00:41 klacke * include/yaws.hrl, include/yaws_api.hrl, man/yaws.1, man/yaws.conf.5, man/yaws_api.5, scripts/Makefile, scripts/yaws.ss, src/yaws.erl, src/yaws_api.erl, src/yaws_compile.erl, src/yaws_config.erl, src/yaws_ctl.erl, src/yaws_log.erl, src/yaws_server.erl: postvar bug by hal snyder, added yaws_api:query_url/1 added the id support and removed the uid stuff, added -j to control trace of a running daemon, bugfixes in the logger, 2004-03-10 12:23 etnt * scripts/yaws.ss: added -pa switch to the yaws start script 2004-03-01 14:21 klacke * src/mime.types: "" 2004-02-29 23:13 klacke * src/: yaws.erl, yaws_revproxy.erl, yaws_server.erl: fixed POST for revproxy 2004-02-26 09:59 jbevemyr * applications/mail/src/mail.erl: Fixed refresh error in webmail. 2004-02-26 09:49 jbevemyr * applications/mail/src/Makefile: [no log message] 2004-02-26 09:45 jbevemyr * applications/mail/: mail/mail.yaws, src/Makefile, src/mail.erl, src/smtp.erl: Added mail sending API in smtp.erl and improved speed of listing for large mail boxes. 2004-02-24 20:52 klacke * man/yaws.conf.5: "" 2004-02-24 20:28 klacke * src/yaws.erl: Date header nug fixed by chandru 2004-02-23 22:58 jbevemyr * applications/mail/: mail/send.yaws, src/mail.erl, src/yaws-webmail.conf: Added proper . escaping form smtp send and pop message. 2004-02-23 00:52 jbevemyr * applications/mail/: mail/mail.js, mail/send.yaws, src/mail.erl: Completed support for attachements. Minor GUI improvements still needed. 2004-02-17 10:36 klacke * man/yaws.conf.5: "" 2004-02-17 10:13 klacke * doc/yaws.tex, include/yaws.hrl, man/yaws.conf.5, src/yaws_config.erl: backed off the is_default patch 2004-02-16 19:19 cschultz * src/yaws_server.erl: [no log message] 2004-02-16 19:08 cschultz * src/yaws_server.erl: Forgot to save a file... Sorry. More on gzip. 2004-02-16 19:00 cschultz * src/: Makefile, yaws.erl, yaws_server.erl, yaws_zlib.erl: Changed compression from `deflate' to `gzip'. 2004-02-16 15:54 cschultz * src/yaws_cgi.erl: Change of my email address. 2004-02-16 15:04 cschultz * src/yaws.erl: Disabled `deflate' for IE. This of course means that we will have to abondon `deflate' (in favor of `gzip') altogether. To do... 2004-02-16 10:40 klacke * doc/yaws.pdf, doc/yaws.tex, include/yaws.hrl, man/yaws.conf.5, src/yaws_api.erl, src/yaws_config.erl: patch by tomas abrahamsson to not generate newlines for certain tags in ehtml, as well as default virt server support 2004-02-16 01:41 jbevemyr * applications/mail/: mail/mail.js, mail/tab-bg_active.gif, mail/tab-bg_inactive.gif, mail/tab-hr.gif, mail/tab-left_active.gif, mail/tab-left_inactive.gif, mail/tab-right_active.gif, mail/tab-right_inactive.gif, src/mail.erl: [no log message] 2004-02-16 00:54 jbevemyr * applications/mail/: mail/reply.yaws, src/mail.erl: Added some support for sending attachments, more needed. Cleaned up display message code. 2004-02-14 22:17 cschultz * src/yaws_ls.erl: Modified ALT texts for better appearance in text browsers. 2004-02-14 20:11 cschultz * src/yaws.erl: More deflate bug workarounds. 2004-02-14 18:52 cschultz * src/yaws.erl: Added deflate workaround for buggy clients (w3m) depending on MIME type. 2004-02-14 17:42 cschultz * src/: yaws.erl, yaws_server.erl: Disable `deflate' for Clients with implementations which are believed to be buggy. 2004-02-13 01:03 klacke * config.guess, config.sub, configure, man/yaws.conf.5, man/yaws_api.5, www/EXHEAD, www/bindings.yaws, www/configuration.yaws, www/contact.yaws, www/contribs.yaws, www/dynamic.yaws, www/examples.yaws, www/index.yaws, www/man.yaws, www/news, www/pcookie.yaws, www/readpcookie.yaws, www/redirect.yaws, www/setcookie.yaws, www/setpcookie.yaws, www/ssi.yaws, www/shopingcart/source.html: qnx port + docs overhaul by cschatz@networkadvantage.biz 2004-02-11 22:13 jbevemyr * applications/wiki/scripts/updateWiki.src: [no log message] 2004-02-11 15:30 klacke * include/yaws.hrl, man/yaws.conf.5, src/yaws_config.erl, src/yaws_log.erl, src/yaws_server.erl: added an auth log that keeps track of good/bad 401 requests 2004-02-10 13:24 klacke * vsn.mk: up vsn 2004-02-10 13:22 klacke * src/: yaws.erl, yaws_api.erl, yaws_server.erl: auth + revproxy fix 2004-02-08 03:26 cschultz * src/: yaws_server.erl, yaws_ssl.erl: Make Content-Encoding in yaws_ssl into an atom. 2004-02-08 02:19 cschultz * src/: yaws.erl, yaws_server.erl: Fixed logged length for deflated files. 2004-02-08 01:47 cschultz * include/yaws.hrl, include/yaws_api.hrl, src/yaws.erl, src/yaws_config.erl, src/yaws_server.erl: Support for `Content-Encoding: deflate' using zlib. This feature has to be turned on in the server part of yaws.conf (`deflate = true'). Still experimental and for static files only. Cached files are compressed just once. Large files are compressed on the fly, and only if the mime type makes it seem wothwhile (see yaws_server:compressible_mime_type). No docs so far. 2004-02-06 22:59 klacke * applications/mail/ebin/.empty: [no log message] 2004-02-06 22:51 klacke * ChangeLog: [no log message] 2004-02-06 22:51 klacke * www/news: release 1.41 2004-02-06 22:31 klacke * applications/mail/src/attachment.erl, src/yaws.erl, vsn.mk: "" 2004-02-06 18:05 klacke * applications/mail/README, www/index.yaws: "" 2004-02-06 18:00 klacke * applications/mail/src/: Makefile, attachment.erl, mail.erl: "" 2004-02-06 14:59 klacke * www/icons/yaws_y.gif: "" 2004-02-06 14:48 klacke * www/: HEAD, icons/yaws_y.gif: "" 2004-02-04 21:45 klacke * src/yaws_api.erl: "" 2004-02-01 16:53 cschultz * src/: yaws_api.erl, yaws_cgi.erl, yaws_server.erl: Introduce {redirect_local, {any_path, URI}} and make yaws_cgi use it. 2004-01-27 16:58 klacke * src/yaws.erl: use new hex bifs 2004-01-27 16:36 klacke * man/yaws_api.5, src/yaws_compile.erl, src/yaws_server.erl, www/EXHEAD, www/bindings.yaws, www/man.yaws, www/redirect.yaws: documented jockes new bindings feature 2004-01-26 23:42 jockeg * src/: yaws_api.erl, yaws_compile.erl, yaws_server.erl: The yaws callback out/1 can now return {bindings, [{Key, Value}]}. All bindings can then be used in the rest of yaws code (in HTML source and within erl tags). In HTML source %%Key%% is expanded to Value and within erl tags yaws_api:get_binding(Key) can be used to extract Value. With this addition it is easier to write transparant yaws code making it easier to to work together with Web people knowing little or nothing about Erlang. A stupid example: ---- $ cat ex.yaws <erl> out(A) -> {bindings, [{"A", "foo"}, {"B", "baz"}]}. </erl> <html> <body> <p>%%A%%</p> <p><font size="4">%%A%% != %%B%%</font></p> <p>An enormous amount of plain html source here.</p> <erl> out(A) -> Value = yaws_api:binding("A"), {ehtml, {ul, [], [{li, [], Value}, {li, [], "gazonk"}]}}. </erl> %%A%% = %%A%% (hit me) </body> </html> ---- Which expands to: <html> <body> <p>foo</p> <p><font size="4">foo != baz</font></p> <p>An enormous amount of plain html source here.</p> <ul> <li>foo</li> <li>gazonk</li></ul> foo = foo (hit me) </body> </html> 2004-01-24 17:33 cschultz * doc/yaws.tex, include/yaws.hrl, man/yaws.conf.5, src/yaws_config.erl, src/yaws_server.erl: Made the php executable configurable 2004-01-22 21:42 jbevemyr * src/yaws_server.erl, doc/yaws.tex: Added support for 301, 303, and 307 redirects. 2004-01-18 07:59 lpsmith * src/yaws_server.erl: Added #arg{} to the out/1 return values. Fixed redirect bug when adding a slash to a URL with a query. Returns a more informative 400 instead of 403 on malformed urls. Cleaned up a bit of debugging code that was left behind. 2004-01-13 21:56 mbj * src/yaws_ls.erl: modified file listing layout, implemented sort based on name, date and size, and direction 2004-01-10 23:05 cschultz * src/yaws_cgi.erl: Added CGI variable REQUEST_URI 2004-01-09 07:44 lpsmith * src/yaws_server.erl: when user directories/directory listings are disabled, we now return a 404 instead of a 403. 2003-12-21 12:56 jbevemyr * applications/wiki/: src/wiki.erl, wiki/WikiPreferences.files/back.gif, wiki/WikiPreferences.files/forward.gif, wiki/WikiPreferences.files/index.gif, wiki/WikiPreferences.files/kamera.gif: [no log message] 2003-12-21 12:37 jbevemyr * applications/wiki/wiki/slideShow.yaws: Added slideShow.yaws. 2003-12-20 22:10 klacke * doc/yaws.pdf, src/yaws_api.erl, src/yaws_compile.erl, src/yaws_server.erl, www/index.yaws: timestamp on the ssi files 2003-12-19 16:05 klacke * src/yaws_api.erl: ssi for ehtml expander as well 2003-12-19 00:34 klacke * src/: yaws.erl, yaws_revproxy.erl: slash_append 2003-12-18 21:34 klacke * www/news, man/yaws.conf.5, src/Makefile, src/yaws_revproxy.erl, src/yaws_server.erl, www/EXHEAD, www/index.yaws: "" 2003-12-18 21:15 klacke * ChangeLog: prepare for 1.40 release 2003-12-18 17:23 klacke * include/yaws.hrl, src/yaws_config.erl, src/yaws_revproxy.erl, src/yaws_server.erl: revproxy fixes 2003-12-17 23:26 klacke * src/yaws_api.erl, src/yaws_server.erl, www/arg.yaws, www/man.yaws, www/news, www/readcookie.yaws, www/readpcookie.yaws: "" 2003-12-17 15:21 klacke * www/shopingcart/: shopcart.erl, shopcart.erl: "" 2003-12-17 15:18 klacke * include/yaws_api.hrl, man/yaws_api.5, src/yaws_api.erl, src/yaws_compile.erl, www/index.yaws, www/man.yaws, www/post.yaws, www/query.yaws, www/redirect.yaws, www/ssi.yaws: postvar(), queryvar(), ssi docs 2003-12-17 01:19 klacke * vsn.mk, include/yaws_api.hrl, www/configuration.yaws, www/dynamic.yaws, www/index.yaws, www/man.yaws, www/query.yaws, www/ssi.yaws, www/ssi/dynamic.1, www/ssi/dynamic.2, www/ssi/dynamic.3: ssi include with var expansion + docs 2003-12-16 20:23 klacke * src/yaws_api.erl, src/yaws_server.erl, www/EXHEAD, www/ssi.yaws, www/ssi_ex1: "" 2003-12-16 10:23 jbevemyr * src/yaws_server.erl: Fixed redirect local to handle {net_path, _} 2003-12-16 00:44 klacke * include/yaws.hrl, include/yaws_api.hrl, src/Makefile, src/yaws.erl, src/yaws_api.erl, src/yaws_config.erl, src/yaws_revproxy.erl, src/yaws_server.erl, src/yaws_ssl.erl, src/yaws_ticker.erl, www/TOPTAB, www/arg.yaws, www/embed.yaws, www/post.yaws, www/readcookie.yaws, www/readpcookie.yaws, www/session.yaws, www/session1.yaws, www/setcookie.yaws, www/setpcookie.yaws, www/upload0.yaws: first almost working vsn of revproxy 2003-12-09 17:45 jbevemyr * applications/mail/src/mail.erl: Fixed session starvation problem. 2003-12-05 16:09 jbevemyr * include/yaws_api.hrl, src/yaws_api.erl, src/yaws_html.erl: Added set cookie parser 2003-12-03 14:51 klacke * src/yaws_compile.erl: -yawsfile patcg from tobbe 2003-12-03 10:01 jbevemyr * src/yaws_html.erl: [no log message] 2003-11-28 12:06 jbevemyr * src/yaws_api.erl: Fixed byg in ehtml_attr_expander. 2003-11-27 12:49 jbevemyr * src/: Makefile, yaws_html.erl: Added html->ehtml parser. 2003-11-27 12:43 jbevemyr * applications/mail/src/mail.erl: Fixed problem with quoted addresses 2003-11-25 01:08 klacke * src/yaws_server.erl: changed behaviour when yaws cannor bind() to addr, to just log and not fail startup completely 2003-11-25 00:50 klacke * www/: EXHEAD, embed.yaws, ybed.erl: "" 2003-11-24 15:06 klacke * src/: yaws.erl, yaws_api.erl: timezone fix, crashed on odd timezones 2003-11-24 14:47 klacke * src/yaws_api.erl: mime type patch by Rob Schmersel 2003-11-20 22:24 jbevemyr * applications/mail/src/mail.erl: Various webmail fixes. 2003-11-14 12:08 jbevemyr * include/yaws.hrl: Security fix: turned off tilde expand and directory listing by default. 2003-11-11 19:49 jbevemyr * applications/mail/TODO: [no log message] 2003-11-11 19:41 jbevemyr * src/yaws_api.erl: Fixed problem with checking for quotes in attribute values. You can now use {check,Key,Value} to make ehtml choose the proper qote for the Value part. Without the check keyword the default quote will be used. 2003-11-11 19:39 jbevemyr * applications/mail/src/mail.erl: Fixed problem with locked mail boxes. 2003-11-10 23:39 klacke * vsn.mk: [no log message] 2003-11-10 23:28 klacke * Makefile, applications/mail/README, applications/mail/src/Makefile, applications/mail/src/defs.hrl, applications/mail/src/mail.erl, applications/mail/src/yaws-webmail.conf, src/yaws.erl, src/yaws_api.erl, src/yaws_config.erl, www/contribs.yaws: added proper config file support to the webmail 2003-11-10 22:09 klacke * ChangeLog, applications/webmail/HEAD, applications/webmail/Makefile, applications/webmail/TOP, applications/webmail/att.yaws, applications/webmail/blurulr3.gif, applications/webmail/blurulr4.gif, applications/webmail/compose.yaws, applications/webmail/index.yaws, applications/webmail/logout.yaws, applications/webmail/mail.gif, applications/webmail/mstil.css, applications/webmail/pop3lib_cli.erl, applications/webmail/read_mail.yaws, applications/webmail/rmail.yaws, applications/webmail/smtp_client.erl, applications/webmail/test.erl, applications/webmail/webmail.erl, applications/webmail/webmail.hrl, applications/webmail/webmail_login.yaws, applications/webmail/webmail_login_post.yaws, applications/webmail/ylwmail.gif: [no log message] 2003-11-10 00:08 jbevemyr * applications/mail/src/mail.erl: Mail address handling cleaned up. 2003-11-09 23:01 jbevemyr * src/yaws_api.erl: Fixed bug in url_encode and modified ehtml to use alternate quote for string attributes if the quote character occurs in the string. 2003-11-09 22:01 jbevemyr * scripts/redhat/yaws.init.d: Redhat init script bug. 2003-11-05 23:44 jbevemyr * applications/mail/src/mail.erl: WebMail improvements - line wrapping and best content type selection for multipart/alternative 2003-11-04 23:09 jbevemyr * applications/mail/src/mail.erl: Added support for displaying forwarded messages. 2003-11-04 23:08 jbevemyr * src/yaws_api.erl: Extended parse_multi to cover one more special case for MIME parsing. 2003-11-04 14:44 cschultz * src/yaws.erl: Removed dead code. 2003-11-04 11:28 mikl * applications/wiki/src/: wiki.erl, wiki_templates.erl: The action bar can now be configured in the wiki_templates modules. 2003-11-04 01:16 jbevemyr * src/yaws_api.erl: Exposed parse_multipart, now used by mail app as well. 2003-11-04 01:15 jbevemyr * applications/mail/src/mail.erl: Added basic multipart support. 2003-11-01 16:04 mikl * applications/wiki/: Makefile, start.sh, wiki.conf: Added a process to release an independant tarball of the Wiki. This will allow optional standalone distribution, while depending on a local install of Yaws. 2003-10-30 15:26 jbevemyr * applications/mail/: mail/reply.yaws, src/mail.erl: Added message delete in webmail 2003-10-30 00:22 jbevemyr * applications/mail/: Makefile, README, include.mk, vsn.mk, mail/compose.yaws, mail/headers.yaws, mail/index.yaws, mail/listop.yaws, mail/login.yaws, mail/logout.yaws, mail/mail.yaws, mail/reply.yaws, mail/send.yaws, mail/showmail.yaws, mail/spacer.gif, mail/tool-delete.gif, mail/tool-div.gif, mail/tool-newmail.gif, mail/tool-send.gif, mail/view-mark.gif, src/Makefile, src/defs.hrl, src/mail.erl, src/mail_vsn.template: Added a another WebMail example application :-). Includes a cookie based session server, among other things. 2003-10-27 21:04 jbevemyr * src/yaws_server.erl: Added support for {redirect_local, {rel_path, Path}} 2003-10-26 22:04 mikl * applications/wiki/src/wiki_to_html.erl: Fixed an ugly bug I previously introduced (Due to some thing in the code that need refactoring. 2003-10-26 21:30 mikl * applications/wiki/src/: wiki_plugin_menu.erl, wiki_to_html.erl: Menu plugin is now working; Links in menu are presented without the "category" prefix. 2003-10-22 23:56 mikl * applications/wiki/src/: Makefile, utils.erl, wiki.erl, wiki_format_txt.erl, wiki_utils.erl: The plugin menu is now working. You can add list of page based on their Prefix. 2003-10-22 22:42 mikl * applications/wiki/src/: Makefile, utils.erl, wiki.erl, wiki_utils.erl: Added last date-time of modification of a page. 2003-10-20 18:22 mikl * applications/wiki/: src/Makefile, src/wiki_format_txt.erl, src/wiki_plugin_backlinks.erl, src/wiki_plugin_dummy.erl, src/wiki_utils.erl, wiki/FormattingWikiPages.wob: Started coding the plugin architecture: dummy and backlinks are provided as example 2003-10-20 10:58 mikl * applications/wiki/: src/wiki_format_txt.erl, wiki/WikiPreferences.wob, wiki/WikiPreferences.files/ftp.png, wiki/WikiPreferences.files/http.png, wiki/WikiPreferences.files/https.png, wiki/WikiPreferences.files/interwiki.png, wiki/WikiPreferences.files/mailto.png, wiki/WikiPreferences.files/url.png: Added Wiki icons for external http links and mailto links 2003-10-04 20:46 klacke * www/index.yaws: "" 2003-10-04 20:36 klacke * configure, www/contribs.yaws: "" 2003-09-24 16:13 klacke * c_src/setuid_drv.c: "" 2003-09-21 00:42 jbevemyr * src/yaws_server.erl: Attempted to fix redirect problem when a host header isn't present, or when rhost or rport is present. We first look for an rhost setting and if that is missing we look for a host header, if that is also missing we use the servername and rport or port. 2003-09-21 00:18 jbevemyr * src/yaws_server.erl: Reverted previous redirect_local fix. 2003-09-16 06:44 lpsmith * src/yaws_server.erl: We now return 403 on relative paths and other malformed requests. Also some small code clean ups. I really wish I had a visual browser for dataflow analysis... it would make simplifing the code much easier, as well as give one a quick rundown of code you aren't familiar with. 2003-09-15 03:38 lpsmith * doc/yaws.tex: Updated documentation relating to WWW-Authenticate. 2003-09-15 03:12 lpsmith * include/yaws.hrl, src/yaws_server.erl: Removed unused fields "q" and "wwwauth" in the #urltype{} record. Removed unused function yaws_server:unflat(). 2003-09-09 21:07 jbevemyr * src/yaws_server.erl: Fixed problem with serving cached files. 2003-09-09 02:53 lpsmith * src/yaws_config.erl: [no log message] 2003-09-09 00:49 klacke * c_src/Makefile: [no log message] 2003-09-09 00:43 klacke * configure, configure.in, include.mk.in, vsn.mk, c_src/Makefile, scripts/Install, scripts/Makefile, scripts/mangle, scripts/yaws.ss, src/yaws.erl, src/yaws_compile.erl, src/yaws_config.erl, src/yaws_ctl.erl, src/yaws_log.erl, src/yaws_server.erl: first attempt to run properly under cygwin 2003-09-08 23:02 lpsmith * src/yaws_config.erl: Removed the code that checks that a directory exists in the case of: <auth> dir= ... </auth> as www-authentication is now specified by server path and not filesystem path. 2003-09-08 22:37 lpsmith * src/yaws_server.erl: WWW-Authentication directories are now specified by server path and not filesystem path. Code cleanup for www-authentication. Major authentication enhancements to come. Numerous other code cleanups, focusing on reducing the number of arguments passed to various functions. The biggest change is that the query part of a URL isn't passed through all the URL-parsing functions. #urltype.q is now unused, should remove it at some point in the future. We update the ARG record a lot less now. 2003-09-04 13:15 cschultz * src/yaws_server.erl: Fixed bug in deliver_dyn_part. 2003-09-03 22:36 jbevemyr * src/yaws_server.erl: Fixed problem when dynamic file only returned {redirect, X} or {redirect_local, Y}. 2003-08-28 22:42 klacke * TODO: "" 2003-08-25 23:09 klacke * doc/yaws.pdf, man/yaws.1, scripts/yaws.ss: -sname and mnesia flag added to start script 2003-08-25 22:22 klacke * ChangeLog: "" 2003-08-25 22:21 klacke * vsn.mk, doc/yaws.pdf, man/yaws.1, man/yaws.conf.5, scripts/yaws.ss, src/yaws.erl, src/yaws_config.erl, src/yaws_debug.erl, src/yaws_log.erl, src/yaws_server.erl, www/index.yaws: added -x flag for tty trace and did the 1.3 release 2003-08-25 20:06 klacke * include.mk.in: removed the -b beam flag 2003-08-25 12:06 cschultz * doc/yaws.tex, man/yaws_api.5, src/yaws_api.erl: Make call_cgi available in yaws_api. 2003-08-25 11:31 cschultz * src/yaws_server.erl: [no log message] 2003-08-25 11:29 cschultz * include/yaws_api.hrl: comment to arg record field `pathinfo' 2003-08-24 22:09 cschultz * doc/Makefile: Call LaTeX twice. 2003-08-24 22:08 cschultz * doc/yaws.tex: arg record out value `page' configuration variable `allowed_scripts' CGI chapter 2003-08-24 17:56 cschultz * man/yaws.1: -S, -load, -check 2003-08-24 17:55 cschultz * man/yaws_api.5: Changes to arg record, {page, {Options, Page}}, comment on returning a list of values. 2003-08-24 17:53 cschultz * man/yaws.conf.5: option allowed_scripts 2003-08-23 22:52 cschultz * src/yaws.erl: Minor optimization in split_sep. 2003-08-23 17:07 cschultz * src/yaws_cgi.erl: Correctly(?) combine several Cookie headers. 2003-08-23 16:38 cschultz * src/yaws_ssl.erl: Better header parsing (again), plus a small optimization. 2003-08-23 16:33 cschultz * src/yaws.erl: Added function strip_spaces to go with is_space. 2003-08-21 21:39 jbevemyr * applications/wiki/scripts/Makefile: Fixed make install problem for wiki 2003-08-19 16:07 klacke * scripts/: Install, darwin/README, darwin/Yaws.StartupItem, darwin/Yaws.plist: Darwin /etc scripts support supplied by Eric Baur 2003-08-16 11:42 klacke * config.guess, config.sub, configure, configure.in: darwin support in configure scripts 2003-08-16 11:41 klacke * src/mime_type_c.erl: recursion bug 2003-08-11 16:57 cschultz * src/yaws_cgi.erl: Now works with partial_post_size set. 2003-08-11 16:54 cschultz * src/yaws_server.erl: Minor changes to get_client_data. 2003-08-07 01:53 cschultz * src/yaws_server.erl: Fixed yet another ssl related bug. 2003-08-06 20:03 cschultz * src/yaws_cgi.erl: Added variable HTTP_COOKIE. 2003-08-05 22:27 cschultz * src/yaws_ssl.erl: Report connection closure istead of `exit'ing. 2003-08-03 18:54 cschultz * src/yaws_server.erl: Yaws files and appmods can return {page, {Options, Page}} instead of {page, Page}. Options is (an option or) a deep list of options. At the moment an option is {header, Header}. I thought this might be useful for Vary or Content-Location headers. 2003-08-01 17:04 cschultz * src/: yaws_ls.erl, yaws_server.erl: Mainly new HEAD request handling. 2003-08-01 17:01 cschultz * src/yaws.erl: [no log message] 2003-08-01 16:57 cschultz * src/yaws_cgi.erl: Bug fix: Don't assume headers.host is defined. 2003-07-30 23:13 cschultz * src/yaws.erl: Bug fix regarding my last ci: When sending partial content, set status code to 206 accordingly. 2003-07-30 22:55 cschultz * src/yaws_server.erl: More faithful access logs in connection with {page, ...}. 2003-07-30 22:11 cschultz * include/yaws.hrl, src/yaws.erl, src/yaws_server.erl: For GETs on regular files: Added support for Content-Range, If-Range, If-Match, expanded support for If-None-Match. 2003-07-29 14:05 cschultz * src/yaws_server.erl: [no log message] 2003-07-26 00:14 cschultz * src/: yaws_server.erl, yaws_ssl.erl: Answer bad requests. 2003-07-23 22:59 cschultz * src/yaws_ssl.erl: Do not let SSL process die on unrecognized request. 2003-07-23 22:58 cschultz * src/yaws_server.erl: [no log message] 2003-07-23 22:48 cschultz * src/yaws_server.erl: For forbidden script types return 403, not 404. 2003-07-22 11:49 cschultz * include/yaws.hrl, src/yaws_config.erl, src/yaws_server.erl: Made allowed script types (yaws, php, cgi) configurable. 2003-07-21 18:24 cschultz * src/yaws_cgi.erl: Return more headers 2003-07-19 14:51 cschultz * src/yaws_cgi.erl: Accept different capitalizations of `Content-type'. 2003-07-17 01:16 cschultz * include/yaws.hrl, include/yaws_api.hrl, src/Makefile, src/mime_type_c.erl, src/yaws_cgi.erl, src/yaws_server.erl: Added CGI and PHP support. Also for a request like /a/b/c.xxx/d/e with xxx being one of `yaws', `cgi' or `php' and c.xxx being a plain file, /a/b/c.xxx is called with Arg#arg.pathinfo, respectively the environment variable PATH_INFO, set to `/d/e'. 2003-07-17 01:09 cschultz * src/yaws_ls.erl: Do not show full path. 2003-07-17 01:06 cschultz * scripts/yaws.ss, src/yaws_ctl.erl: Added command `-load' to yaws script. 2003-07-17 01:04 cschultz * src/: yaws.erl, yaws_ticker.erl: Moved ticker function to separate module to ease purging of module `yaws'. 2003-07-16 17:16 cschultz * src/yaws_server.erl: Some code clean-up. 2003-07-15 03:33 cschultz * src/yaws_ssl.erl: Made header parsing more robust with respect to capitalizations. 2003-07-15 00:14 cschultz * src/yaws_server.erl: Fixed bug with SSL and post data 2003-07-14 00:46 jbevemyr * applications/wiki/src/wiki.erl: Improved speed of thumbs in slideshow 2003-07-13 01:31 cschultz * include/yaws.hrl, src/yaws.erl, src/yaws_server.erl: Log file size for dynamic pages. 2003-07-13 01:17 cschultz * src/yaws_ssl.erl: Make sure the whole header is received. Added more header parsing. 2003-07-13 01:12 cschultz * src/yaws.erl: Changed etag function. 2003-07-13 00:13 lpsmith * include/yaws_api.hrl: Added the field server_path, which will store the parsed and normalized path of the request string. This is in preparation for some significant clean-ups of the yaws_server.erl code. 2003-07-12 05:25 lpsmith * src/yaws_api.erl: Improved path handling: path_norm/1 removes all occurences of double slashes and the directories "." and "..". url_decode_q_split now calls this function on the path that it returns. This is to fix a variety of www-authenticate related security bugs. Previously, it was possible to access any www-auth protected directory by inserting a "/./" before the directory, i.e. by requesting "/./confidential/file.html". 2003-07-12 01:40 lpsmith * src/yaws_404.erl: Fixed Cross-Site Scripting vunerability by html-quoting the path displayed in the error message. 2003-07-09 22:25 jbevemyr * applications/wiki/src/: wiki.erl, wiki_format_txt.erl: Added auto viewing of slides. 2003-07-09 21:33 jbevemyr * applications/wiki/src/wiki.erl: Minor slide show enhancement. 2003-07-09 20:00 jbevemyr * applications/wiki/scripts/updateWiki.src: [no log message] 2003-07-09 19:57 jbevemyr * applications/wiki/: src/wiki.erl, wiki/getMidSize.yaws, wiki/getThumb.yaws, wiki/thumbIndex.yaws: Added thumbnail index to slideshow and scaling of images in slideshow using convert 2003-07-03 03:03 jbevemyr * src/yaws_log.erl: Log format fix 2003-06-27 15:16 jbevemyr * src/yaws_config.erl: Fixed server sorting bug 2003-06-25 17:07 jbevemyr * src/yaws_api.erl: Fixed set cookie problem with lynx 2003-06-23 17:26 klacke * src/yaws_server.erl: "" 2003-06-23 16:07 klacke * src/yaws_server.erl: return last value of the list returned from out/1 2003-06-23 12:19 klacke * src/: yaws_config.erl, yaws_log.erl: missing integer_conversion in ssl conf depth and verify 2003-06-23 12:15 klacke * src/yaws_log.erl: setuid code had broken 2003-06-17 12:57 klacke * src/: yaws.erl, yaws_server.erl: possibility to turn off transfer-encoding: chunked and explicitly set content length 2003-06-01 21:25 klacke * www/index.yaws: "" 2003-06-01 21:25 klacke * ChangeLog: 1.22 checkin 2003-06-01 20:35 klacke * doc/yaws.pdf: "" 2003-05-27 14:56 klacke * src/yaws_api.erl: the ehtml expander code has to be updated again in order to not interfer with rendering when it comes to genereated newlines 2003-05-26 23:58 klacke * configure, configure.in, vsn.mk, scripts/Install, scripts/Makefile, scripts/ntpath.sh, scripts/yaws.init.d, scripts/yaws.ss, scripts/redhat/yaws.init.d, scripts/suse/yaws.init.d, src/yaws_config.erl, src/yaws_server.erl: cvs fixes + install scripts gentoo/suse/redhat 2003-05-24 15:36 jbevemyr * applications/wiki/scripts/updateWiki.src: Fixed install problem. 2003-05-20 00:31 klacke * src/yaws_api.erl: added newlines to strategic places in ehtml_expand/1 and ehtml_exapnder/1. No newlines after img tags. 2003-05-19 23:55 jbevemyr * applications/wiki/wiki/FormattingWikiPages.wob: [no log message] 2003-05-19 23:42 jbevemyr * applications/wiki/src/wiki_format_txt.erl: Added expires region. 2003-05-17 23:58 jbevemyr * applications/wiki/src/wiki.erl: Added number table for slideshow in Wiki 2003-05-17 23:25 jbevemyr * src/yaws_config.erl, src/yaws_server.erl, include/yaws.hrl, man/yaws.conf.5: Added rhost option for setting explicit redirect host (and port if needed) 2003-05-17 21:52 jbevemyr * applications/wiki/wiki/FormattingWikiPages.wob: [no log message] 2003-05-17 21:43 jbevemyr * applications/wiki/: Makefile, README, src/wiki_format_txt.erl, wiki/FormattingWikiPages.wob: Added underline macro 2003-05-17 21:42 jbevemyr * applications/wiki/scripts/updateWiki.src: [no log message] 2003-05-17 21:39 jbevemyr * applications/wiki/scripts/: Makefile, updateWiki.sh, updateWiki.src: Minor wiki script fixes 2003-05-17 13:52 jbevemyr * applications/wiki/: README, updateWiki.sh, scripts/Makefile, scripts/getPassword.src, scripts/importFiles.src, scripts/updateWiki.sh, src/wiki.erl: Added some useful scripts 2003-05-16 22:09 jbevemyr * applications/wiki/: updateWiki.sh, updateWiki.sh: [no log message] 2003-05-16 22:05 jbevemyr * applications/wiki/updateWiki.sh: [no log message] 2003-05-16 21:48 jbevemyr * applications/wiki/updateWiki.sh: Added wiki update script 2003-05-16 13:45 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_templates.erl, src/wiki_utils.erl, wiki/WikiPreferences.files/custom.css: Menu is now red when a page is locked. 2003-05-16 13:12 jbevemyr * applications/wiki/src/: wiki.erl, wiki_format_txt.erl: Added header tags =H3= ==H2== ===H1=== 2003-05-14 13:25 klacke * src/yaws_server.erl: more redir fixes 2003-05-13 22:35 jbevemyr * src/yaws_server.erl: Fixed yaws redirect bug 2003-05-13 13:35 klacke * src/: yaws.erl, yaws_debug.hrl, yaws_server.erl: when a gserv() dies, exit app + 302 without content shall have a conten length header, newest mozilla hangs (correctly) on 302's from yaws 2003-05-12 09:56 jbevemyr * applications/wiki/README: [no log message] 2003-05-12 09:53 jbevemyr * applications/wiki/src/wiki.erl: [no log message] 2003-05-12 09:49 klacke * src/yaws_api.erl: newlines added by jocke in bluetail cvs 2003-05-08 23:53 jbevemyr * applications/wiki/src/: wiki.erl, wiki_format_txt.erl: [no log message] 2003-05-08 23:12 jbevemyr * applications/wiki/src/wiki_format_txt.erl: minor bugfixes 2003-05-07 10:13 klacke * scripts/suse/yaws.init.d: "" 2003-05-07 10:09 klacke * scripts/yaws.ss: "" 2003-05-05 01:22 klacke * scripts/gentoo/yaws.ebuild: "" 2003-05-04 23:47 klacke * include.mk.in, scripts/Install, scripts/Makefile, scripts/yaws.init.d, scripts/gentoo/conf.d.yaws, scripts/gentoo/yaws.ebuild: "" 2003-05-04 23:13 klacke * scripts/: Install, gentoo/conf.d.yaws: "" 2003-05-04 21:31 klacke * scripts/Install: "" 2003-05-04 21:24 klacke * scripts/Install: "" 2003-05-04 20:47 klacke * doc/Makefile: "" 2003-05-04 20:34 klacke * scripts/mangle, www/index.yaws: "" 2003-05-04 18:55 klacke * scripts/Install: "" 2003-05-04 18:41 klacke * scripts/: Install, gentoo/yaws.ebuild: "" 2003-05-04 18:21 klacke * Makefile, vsn.mk, doc/Makefile, doc/yaws.pdf, man/Makefile, scripts/Install, scripts/gentoo/conf.d.yaws, scripts/gentoo/init.d.yaws, scripts/gentoo/yaws.ebuild: "" 2003-05-03 21:04 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_format_txt.erl, src/wiki_to_html.erl, wiki/FormattingWikiPages.wob: Added slideshow support. With a slideshow:MySlideShow link on a page you will get a slide show of all the files stored in that page (image files preferably :-) 2003-05-02 23:25 klacke * doc/: Makefile, yaws.tex: nicer latex docs in patch from nniclausse on sourceforge 2003-05-02 22:49 klacke * www/man.yaws: "" 2003-05-02 22:39 klacke * vsn.mk: "" 2003-05-02 22:37 klacke * www/index.yaws: 1.2 checkin 2003-05-02 21:34 klacke * src/yaws_ls.erl: small bugs with listdir, no 0 on chunked encodings, and no url_encode on iso chars in filenames 2003-04-28 23:48 etnt * scripts/Install: Added the setting of etcdir 2003-04-25 10:02 etnt * src/yaws_config.erl: Set the debug entry in #gconf{}, in make_default_gconf/1. 2003-04-22 15:06 klacke * vsn.mk: "" 2003-04-10 12:46 klacke * src/yaws_compile.erl: [no log message] 2003-04-10 12:20 mikl * src/yaws_config.erl: Cosmetic change for logs: Missing ~n. 2003-04-10 10:59 mikl * ChangeLog, Makefile, README, include.mk.in, doc/Makefile, scripts/Install, scripts/Makefile, src/Makefile, www/shopingcart/Makefile: Build chain modifications: Install target directories is now totally controllable; The docs build is optionnal 2003-04-09 13:12 klacke * src/Makefile: [no log message] 2003-04-09 13:04 klacke * src/yaws_compile.erl: use lock on comiler, erlc is not reentrant 2003-03-25 11:14 klacke * src/yaws_server.erl: Bug with cached yaws files with a query part 2003-03-11 06:49 brucefitzsimons * src/yaws_log.erl: Fixed the TZ determination code, its not perfect or fast yet. 2003-03-10 10:25 brucefitzsimons * src/: yaws_log.erl, yaws_server.erl: Added referrer "referer" and user-agent to complete the "combined" log format. It will log - for either field if it is not supplied. The old logging command has been retained for backward compatibility. Also added code to log the time in localtime, and log the offset in the apache/Common Log Format. This is significant for anyone using the logs... 2003-03-06 21:47 jbevemyr * src/yaws_api.erl: Removed 'Version' from set-cookie. 2003-03-06 19:36 klacke * ChangeLog, www/index.yaws: 1.01 checkin 2003-03-06 12:22 klacke * Makefile, src/yaws_compile.erl, src/yaws_server.erl: skip empty space after an </erl> and handle http_error which is generated by the inet_drv.c code. This assumes a patch to the inet_drv.c that actually generates a http_error in this case. Default erl hangs there 2003-03-05 12:46 klacke * src/: yaws.erl, yaws_server.erl: handle 0.9 clients 2003-03-05 12:19 klacke * include.mk, src/yaws_server.erl, include.mk: "" 2003-03-04 23:38 klacke * src/yaws_server.erl: [no log message] 2003-03-03 22:37 jbevemyr * src/: yaws.erl, yaws_server.erl: Added proper support for 'if-none-match' with etag matching 2003-03-03 17:35 klacke * src/yaws_server.erl: "" 2003-02-25 16:12 klacke * src/yaws_api.erl, src/yaws_compile.erl, src/yaws_server.erl, www/man.yaws: Fixed probles with paths that had a query part ending up in the cache 2003-02-25 14:31 klacke * vsn.mk: "" 2003-02-25 14:30 klacke * c_src/setuid_drv.c, src/yaws.erl, src/yaws_config.erl, src/yaws_ctl.erl, src/yaws_log.erl, src/yaws_server.erl: did away with the idiotic calls to id -u as well as the the broken grep in /etc/passwd. Also ensured that .yaws files with a query part don't end up in the cache. They need to be reparsed every time 2003-02-17 20:33 klacke * src/yaws_server.erl: added http version to access log messages 2003-02-08 14:17 klacke * include/yaws.hrl, man/yaws.conf.5, src/yaws_config.erl, src/yaws_debug.erl, src/yaws_server.erl: added the option of disabling dir_listings 2003-02-08 14:04 klacke * src/yaws_server.erl: bug with redir for missing trailing slash together with a query part of the url fixed, found by Erik Pearson <erikp@attbi.com> 2003-02-08 13:53 klacke * src/yaws_server.erl: bug in arg rewrite handling found and fixed by Taavi Talvik 2003-02-08 13:27 klacke * src/yaws_config.erl: bug in ssl config passord parse found by Eric Pearson 2003-01-28 19:27 klacke * src/yaws_server.erl: [no log message] 2003-01-27 23:22 klacke * src/yaws_server.erl: "" 2003-01-27 23:04 klacke * src/yaws_compile.erl, ChangeLog: "" 2003-01-24 00:59 klacke * src/: yaws_compile.erl, yaws_compile.erl: [no log message] 2003-01-23 23:52 klacke * www/index.yaws: [no log message] 2003-01-23 23:43 klacke * vsn.mk: we'ready for production now 2003-01-23 23:38 klacke * src/: yaws_compile.erl, yaws_config.erl, yaws_server.erl: don't log a crash when we get methods we don't support and also a fix in the yaws compiler so that we can compile files that have been originally produced on a win32 machine, the problem was \r\n lines 2003-01-21 14:34 jbevemyr * src/yaws.erl: Made it possible to have multiple set-cookie headers 2003-01-17 15:27 klacke * applications/webmail/test.erl: "" 2003-01-15 17:07 klacke * src/: yaws_api.erl, yaws_server.erl: "" 2003-01-10 13:14 klacke * src/yaws_server.erl: large files became LISTS 2003-01-08 10:29 klacke * www/man.yaws: security bug found by jcortner@cvol.net 2003-01-08 10:21 klacke * src/yaws_server.erl: "" 2003-01-05 19:15 klacke * www/man.yaws: "" 2002-12-27 00:30 jbevemyr * applications/wiki/src/wiki.erl: [no log message] 2002-12-10 11:57 mikl * www/shopingcart/Makefile: In the shopping cart Makefile, one of the generated beam file was not removed with the make clean command. 2002-12-10 10:30 mikl * www/stats.yaws: Modified stats.yaws to add total number of hits at the end of each virtual host statistic table. 2002-12-09 23:16 mikl * src/yaws_config.erl: mremond: Made a very small change in yaws_config.erl. You can now use relative directory name in a yaws configuration file. 2002-12-09 23:15 mikl * src/yaws_config.erl: yaws_config.erl 2002-12-06 00:34 klacke * src/: yaws_log.erl, yaws_server.erl: "" 2002-12-05 23:29 klacke * src/mime.types: "" 2002-12-05 12:27 klacke * src/yaws_server.erl: "" 2002-12-03 19:37 klacke * src/yaws_api.erl: "" 2002-12-03 19:34 klacke * src/yaws_api.erl: "" 2002-12-03 13:19 klacke * src/: yaws_api.erl, yaws_config.erl, yaws_debug.erl, yaws_log.erl, yaws_server.erl: "" 2002-12-03 12:25 klacke * src/yaws.erl: erase headers 2002-12-01 20:36 klacke * www/upload.yaws: "" 2002-12-01 20:24 klacke * ChangeLog, TODO, vsn.mk, doc/yaws.tex, man/yaws.conf.5, www/TOPTAB, www/contribs.yaws, www/index.yaws: "" 2002-12-01 13:24 klacke * src/yaws_log.erl: bugs in wrap log 2002-11-29 19:30 klacke * src/yaws_log.erl, src/yaws_ls.erl, src/yaws_server.erl, www/configuration.yaws, www/index.yaws: Even more fixes on the change user thingie, fixed a bug with dir listings together with ~expansion Cleanup code removed old dead code catch around broken requests from nimda et at.el which produced crashes in our report log + bugdix on 403 replies 2002-11-29 14:33 klacke * src/yaws_server.erl: "" 2002-11-29 14:08 klacke * src/yaws_404.erl: "" 2002-11-29 14:02 klacke * src/yaws_log.erl: "" 2002-11-29 14:01 klacke * include.mk: run as nobody may work now 2002-11-29 13:50 klacke * src/: yaws_log.erl, yaws_server.erl: "" 2002-11-28 22:14 klacke * scripts/yaws.ss: "" 2002-11-28 20:32 klacke * README, configure, configure.in: "" 2002-11-28 00:24 klacke * Makefile, config.guess, config.sub, include.mk, include.mk.in, install-sh, c_src/Makefile, c_src/setuid_drv.c, include/yaws.hrl, man/yaws.conf.5, src/yaws.erl, src/yaws_config.erl, src/yaws_ctl.erl, src/yaws_log.erl, src/yaws_server.erl, src/yaws_sup.erl: added ability to run as different user than root 2002-11-27 11:13 klacke * src/yaws_api.erl: "" 2002-11-26 19:50 klacke * src/: yaws_ls.erl, yaws_server.erl: "" 2002-11-26 19:21 klacke * www/stil.css: "" 2002-11-26 19:05 klacke * www/: EXHEAD, code.yaws, index.yaws, pcookie.yaws, session.yaws, session1.yaws: "" 2002-11-26 17:11 klacke * src/yaws.erl, src/yaws_api.erl, src/yaws_ctl.erl, www/arg.yaws, www/code.yaws, www/index.yaws, www/upload0.yaws: "" 2002-11-25 23:52 klacke * examples/ebin/.empty, examples/include/.empty, scripts/make-release, scripts/make-release, scripts/make-release: "" 2002-11-25 23:35 klacke * doc/Makefile: "" 2002-11-25 23:34 klacke * CHANGELOG, ChangeLog, vsn.mk, www/index.yaws, www/static.html: vsn 0.59 ci 2002-11-25 23:00 klacke * www/TOPTAB: "" 2002-11-25 22:57 klacke * man/yaws_api.5, www/EXHEAD, www/arg.yaws, www/doc.yaws, www/upload.yaws, www/upload0.yaws, www/shopingcart/Makefile, www/shopingcart/source.html: "" 2002-11-25 22:45 klacke * src/yaws_ctl.erl: "" 2002-11-25 21:47 jbevemyr * src/yaws_api.erl: [no log message] 2002-11-25 20:59 lukeg * src/yaws_api.erl: Moved ehtml_expand in here. Added ehtml_expander/1 for fast reusable EHTML templates. 2002-11-25 20:58 lukeg * src/yaws_server.erl: Moved ehtml_expand into yaws_api 2002-11-22 17:13 klacke * src/: yaws.erl, yaws_api.erl: "" 2002-11-22 16:07 klacke * include/yaws.hrl, src/yaws.erl, src/yaws_api.erl, src/yaws_ctl.erl, src/yaws_ls.erl, src/yaws_server.erl: "" 2002-11-22 15:00 klacke * src/yaws_server.erl: "" 2002-11-22 00:12 klacke * src/yaws_server.erl: "" 2002-11-21 23:31 klacke * vsn.mk, include/yaws.hrl, src/yaws.erl, src/yaws_404.erl, src/yaws_api.erl, src/yaws_debug.erl, src/yaws_server.erl: outh record, the outgoing headers are built up into a record now, much cleaner 2002-11-21 22:36 lukeg * src/: yaws_api.erl, yaws_server.erl: Added a blocking / flow control option for streaming content. The interface is yaws_api:stream_chunk_deliver_blocking/2 2002-11-20 21:18 klacke * scripts/yaws.ss, src/yaws_ctl.erl: "" 2002-11-20 17:19 klacke * scripts/yaws.ss, src/yaws_compile.erl, src/yaws_ctl.erl: -check arg 2002-11-20 14:53 klacke * include/yaws_api.hrl, man/yaws_api.5, src/yaws.erl, src/yaws_api.erl: parse_url 2002-11-20 13:21 klacke * src/yaws_api.erl: "" 2002-11-20 10:59 jbevemyr * include/yaws.hrl, src/yaws_config.erl, src/yaws_server.erl: [no log message] 2002-11-20 10:37 jbevemyr * src/: yaws_server.erl, yaws.erl: [no log message] 2002-11-20 10:17 jbevemyr * include/yaws.hrl, src/yaws_config.erl, src/yaws_server.erl: added servername to config file 2002-11-19 23:14 etnt * src/yaws_server.erl: removed reverse of appmod_prepath 2002-11-19 22:52 jbevemyr * src/yaws_config.erl: Added support for quoted strings in yaws.conf 2002-11-19 20:15 jbevemyr * include/yaws.hrl, src/yaws_server.erl: Fixed redirect_local 2002-11-19 00:12 etnt * include/yaws_api.hrl, src/yaws_server.erl: Added #args.appmod_prepath which contains the path in front of <appmod><appmoddata> 2002-11-18 23:13 klacke * src/yaws_server.erl: "" 2002-11-18 23:00 jbevemyr * src/yaws_api.erl: Implemented setcookie/6 2002-11-18 22:52 jbevemyr * src/yaws_api.erl: [no log message] 2002-11-18 22:45 klacke * src/mime_type_c.erl: "" 2002-11-18 20:28 klacke * src/yaws_server.erl: "" 2002-11-18 17:22 klacke * src/: yaws_debug.erl, yaws_server.erl: "" 2002-11-18 08:53 klacke * src/yaws_compile.erl, src/yaws_ls.erl, www/TOPTAB, www/man.yaws, www/simple.yaws: "" 2002-11-16 18:10 klacke * src/: yaws_api.erl, yaws_compile.erl, yaws_compile.erl: "" 2002-11-15 15:07 lukeg * src/yaws_api.erl: Bugfixed url_encode/1 (really this time!) 2002-11-15 14:52 klacke * src/: yaws_api.erl, yaws_server.erl: "" 2002-11-15 14:32 lukeg * src/yaws_api.erl: Bugfixed url_encode/1 2002-11-13 16:30 lukeg * src/yaws_server.erl: Bigfix in ehtml_attrs: now "quoting" the value. 2002-11-13 00:30 klacke * src/: yaws.erl, yaws_api.erl, yaws_server.erl: "" 2002-11-12 21:30 klacke * src/yaws_server.erl: "" 2002-11-12 17:57 lukeg * src/yaws_server.erl: Heavily optimized ehtml_expand by converting io_lib:format's into conses. 2002-11-12 17:49 klacke * man/yaws_api.5, src/yaws_server.erl: page retval 2002-11-12 17:35 klacke * src/yaws_server.erl: "" 2002-11-12 12:36 klacke * src/: yaws.erl, yaws_api.erl, yaws_server.erl: "" 2002-11-11 10:47 klacke * include/yaws.hrl, src/yaws_api.erl: "" 2002-11-10 23:19 klacke * include/yaws.hrl, man/yaws_api.5, src/yaws_api.erl, src/yaws_config.erl, src/yaws_debug.erl, src/yaws_server.erl: "" 2002-11-10 23:03 klacke * doc/: a.eps, b.eps, layout.eps, yaws.tex, yaws_head.eps: user manual ok 2002-11-09 10:53 klacke * doc/Makefile: "" 2002-11-08 17:21 etnt * man/yaws.conf.5: Added explanation for 'start_mod' and the opaque context. 2002-11-08 16:33 etnt * include/yaws.hrl, src/yaws_config.erl, src/yaws_server.erl: More opaque stuff. 2002-11-08 14:40 jbevemyr * src/yaws_server.erl: [no log message] 2002-11-08 13:26 klacke * src/: yaws_api.erl, yaws_log.erl, yaws_server.erl: added interactive tty trace 2002-11-08 01:24 klacke * doc/yaws.tex: "" 2002-11-07 02:11 etnt * include/yaws.hrl, src/yaws_config.erl, src/yaws_server.erl: Added a '<opaque>' context to be defined inside a server context. This makes it possible for a user application to get hold of those 'Key = Value' definitions made inside the opaque context. If 'module = <Module>' is defined, a callback: Module:yaws_opaque/1 will be called at startup of the server. The argument of the callback is a list of {Key,Value} tuples as found in the opaque context. 2002-11-07 01:12 klacke * doc/yaws.tex, include/yaws_api.hrl, man/yaws_api.5, src/yaws_api.erl, src/yaws_server.erl, www/arg.yaws: "" 2002-11-06 22:02 klacke * include/yaws.hrl, man/yaws.conf.5, src/yaws.erl, src/yaws_config.erl, src/yaws_server.erl: added arg_rewrite_mod 2002-11-06 14:59 klacke * src/yaws_server.erl: "" 2002-11-06 14:23 klacke * include/yaws.hrl, src/yaws_404.erl, src/yaws_config.erl, src/yaws_server.erl: customized crash messages 2002-11-05 21:51 klacke * man/yaws_api.5, src/yaws_api.erl: "" 2002-11-05 15:02 klacke * src/yaws_server.erl: "" 2002-11-05 13:44 klacke * src/yaws_config.erl: "" 2002-11-05 01:27 klacke * src/: yaws_404.erl, yaws_server.erl: "" 2002-11-05 01:21 klacke * Makefile, doc/Makefile, doc/yaws.tex, include/yaws.hrl: added doc directory 2002-11-05 01:16 klacke * man/yaws.conf.5: "" 2002-11-05 01:12 klacke * src/yaws_config.erl: rewrote ssl conf 2002-11-05 00:49 klacke * src/: Makefile, yaws_404.erl, yaws_api.erl, yaws_config.erl, yaws_server.erl: 404 module added 2002-11-04 23:23 klacke * Makefile, scripts/Makefile, www/configuration.yaws: make local_install target 2002-11-02 17:06 jbevemyr * applications/wiki/src/: wiki.erl, wiki_format_txt.erl: Fixed problem with edit 2002-10-31 00:36 jbevemyr * applications/wiki/src/: wiki.erl, wiki_format_txt.erl: Added mailtoall: wiki tag which creates a mailing list containing all email addresses found in mailto: tags on the page. A convenient way of creating mailing lists. 2002-10-30 21:54 jbevemyr * applications/wiki/: README, src/wiki_templates.erl: Moved the Wiki settings into a wiki page - WikiPrefereces, ie they are now editable from within the Wiki. 2002-10-30 21:50 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_templates.erl, src/wiki_to_html.erl, src/wiki_utils.erl, wiki/WikiPreferences.wob, wiki/allpages.gif, wiki/custom.css, wiki/edit.gif, wiki/editfiles.gif, wiki/editme.gif, wiki/history.gif, wiki/home.gif, wiki/icon.gif, wiki/info.gif, wiki/lastedited.gif, wiki/locked.gif, wiki/normal.gif, wiki/old.gif, wiki/zombies.gif, wiki/WikiPreferences.files/allpages.gif, wiki/WikiPreferences.files/custom.css, wiki/WikiPreferences.files/edit.gif, wiki/WikiPreferences.files/editfiles.gif, wiki/WikiPreferences.files/editme.gif, wiki/WikiPreferences.files/history.gif, wiki/WikiPreferences.files/home.gif, wiki/WikiPreferences.files/icon.gif, wiki/WikiPreferences.files/lastedited.gif, wiki/WikiPreferences.files/zombies.gif: Moved the Wiki settings into a wiki page - WikiPrefereces, ie they are now editable from within the Wiki. 2002-10-29 09:21 jbevemyr * applications/wiki/src/wiki_format_txt.erl: Fixed problem with multiple recipients in a mailto tag 2002-10-28 10:30 jbevemyr * src/yaws_server.erl: Fixed servername:rport so that it is only used if no other server matches. 2002-10-28 10:08 jbevemyr * src/yaws_server.erl: The host header is matched agains the servername and the servername:rport, to support servers behind portmapping firewalls 2002-10-27 21:48 jbevemyr * applications/wiki/: src/wiki.erl, wiki/changePassword.yaws, wiki/changePassword2.yaws: Added change password function 2002-10-26 22:10 jbevemyr * applications/wiki/src/wiki.erl: [no log message] 2002-10-26 17:57 klacke * src/yaws_ctl.erl: "" 2002-10-25 23:45 etnt * applications/wiki/src/Makefile: Now also install correctly on FreeBSD 2002-10-25 12:13 jbevemyr * applications/wiki/: README, src/wiki.erl, src/wiki_to_html.erl, wiki/previewNewPage.yaws: Fixed problems with regions 2002-10-23 14:20 etnt * src/yaws_ls.erl: Fixed the indentation of directory listings. Also, when hoovering over a filename, the size in bytes is displayed. Finally, a README file is inlined at the bottom, if it exist. 2002-10-23 12:11 klacke * src/yaws_server.erl: empty sconfs in embedded mode 2002-10-22 14:44 jbevemyr * src/Makefile: Added make dependence rule for include files. 2002-10-22 12:41 jbevemyr * include/yaws.hrl, man/yaws.conf.5, src/yaws_config.erl, src/yaws_server.erl: Fixed redirects and added rport and rmethod server settings. 2002-10-22 11:00 jbevemyr * src/yaws_server.erl: Fixed redirect code. 2002-10-22 00:03 klacke * vsn.mk: "" 2002-10-21 11:14 klacke * www/contact.yaws: "" 2002-10-18 11:50 klacke * src/yaws_server.erl: "" 2002-10-18 11:40 klacke * man/yaws_api.5: "" 2002-10-18 10:20 klacke * src/yaws_api.erl: "" 2002-10-18 09:41 klacke * src/yaws_log.erl: "" 2002-10-18 00:17 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_yaws.erl, wiki/previewPage.yaws, wiki/storePage.yaws: Added session state to wiki for better page editing 2002-10-17 13:04 klacke * src/yaws_api.erl: "" 2002-10-17 12:07 klacke * src/yaws_api.erl: "" 2002-10-16 16:51 jbevemyr * applications/wiki/src/: wiki.erl, wiki_to_html.erl: Added size title to files 2002-10-16 16:03 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_yaws.erl, wiki/allPages.yaws, wiki/copyFiles.yaws, wiki/deleteFiles.yaws, wiki/editPage.yaws, wiki/editTag.yaws, wiki/finalDeletePage.yaws, wiki/lastEdited.yaws, wiki/previewNewPage.yaws, wiki/previewPage.yaws, wiki/previewTagged.yaws, wiki/putPassword.yaws, wiki/sendMeThePassword.yaws, wiki/storeFiles.yaws, wiki/storeNewPage.yaws, wiki/storePage.yaws, wiki/storeTagged.yaws, wiki/wikiZombies.yaws: Updated wiki with new parse_post_data interfaces. 2002-10-16 14:22 klacke * include/yaws.hrl, src/yaws.erl, src/yaws_ctl.erl, src/yaws_log.erl, src/yaws_ls.erl, src/yaws_server.erl, src/yaws_session_server.erl: introduced opaque data in sconf 2002-10-16 13:55 klacke * include/yaws_api.hrl, src/yaws_api.erl, src/yaws_server.erl: made backwards incompatible change to parse_post_data 2002-10-15 23:48 klacke * include/yaws.hrl, src/yaws_config.erl, src/yaws_debug.erl, src/yaws_server.erl: "" 2002-10-15 16:16 klacke * src/: yaws.erl, yaws_api.erl, yaws_log.erl: log bugs in embedded mode 2002-10-15 15:38 jbevemyr * src/yaws_server.erl: Fixed problem when log is turned off 2002-10-15 14:37 klacke * include/yaws.hrl, include/yaws_api.hrl, man/yaws.conf.5, src/yaws_config.erl, src/yaws_server.erl: fixed tilde username expansion it didn't work, also made thta a configurable in the config file. Added appmods a mechanism whereby an application can fake directory hierachys. Useful for applications that deliver content which isn't html. Many browsers doesn;t (read IE) don't respect the Content-Disposition: header, rather they just use the filename extension to determini which plugin to to render a file 2002-10-14 21:36 jbevemyr * src/yaws_api.erl: Fixed problem with parsing of multipart posts. The problem occured when the parsing of a partial packet terminated in the middle of parsing a possible boundary, for example if a packet ended with a newline. 2002-10-13 23:09 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_yaws.erl, wiki/allPages.yaws, wiki/allRefsToMe.yaws, wiki/createNewPage.yaws, wiki/deletePage.yaws, wiki/editFiles.yaws, wiki/getFile.yaws, wiki/importFiles.yaws, wiki/lastEdited.yaws, wiki/showHistory.yaws, wiki/showOldPage.yaws, wiki/showPage.yaws, wiki/wikiZombies.yaws: Fixed problem with old win 98 IE 2002-10-10 17:32 klacke * src/yaws_server.erl: "" 2002-10-10 16:30 klacke * include/yaws.hrl, src/yaws.erl, src/yaws.hrl, src/yaws_api.erl, src/yaws_compile.erl, src/yaws_config.erl, src/yaws_debug.erl, src/yaws_log.erl, src/yaws_ls.erl, src/yaws_server.erl, src/yaws_ssl.erl: rearr of includefiles 2002-10-10 14:00 klacke * src/yaws_server.erl: bug in embedded mode getenv 2002-10-10 13:12 klacke * src/yaws_server.erl: [no log message] 2002-10-10 13:07 klacke * src/yaws_server.erl: make /tmp/yaws world writeable if we create it 2002-10-10 00:23 klacke * www/todo.yaws: "" 2002-10-09 09:37 klacke * www/: contact.yaws, index.yaws: "" 2002-10-07 23:53 klacke * ChangeLog, vsn.mk, www/index.yaws: vsn 0.56 ci 2002-10-07 23:37 klacke * Makefile, src/mime.types, www/dynamic.yaws, www/shopingcart/Makefile, www/shopingcart/shopcart.erl, www/shopingcart/source.html, www/shopingcart/style.css: added more documentation 2002-10-07 18:26 lukeg * src/yaws_server.erl, src/yaws_api.erl, ChangeLog: Fixed bug and security hole introduced by my previous changes to URL decoding. The problem was that I skipped URL decoding, so you could e.g. read the source to a Yaws file by saying "foo.yaw%73" instead of "foo.yaws". Now we initially decode the URL but not the query part. The query part is decoded in yaws_api:parse_query. It can't be done earlier, because unescaping characters like '&' and '=' would break the parsing. 2002-10-07 15:36 jbevemyr * src/: yaws.hrl, yaws_config.erl: Upped read timeout and made it configurable 2002-10-06 23:59 klacke * include/yaws_api.hrl, man/yaws_api.5, src/yaws_api.erl, src/yaws_session_server.erl, www/EXHEAD, www/shopingcart/buy.yaws, www/shopingcart/cart.yaws, www/shopingcart/index.yaws, www/shopingcart/loginpost.yaws, www/shopingcart/logout.yaws, www/shopingcart/mall.yaws, www/shopingcart/shopcart.erl, www/shopingcart/shopcart_form.yaws, www/shopingcart/style.css: wrote the shopppingcart example 2002-10-06 19:32 jbevemyr * applications/wiki/src/wiki_yaws.erl, src/yaws_config.erl, src/yaws_server.erl: Fixed problem with chunked posts 2002-10-02 13:20 klacke * src/yaws_server.erl: bug in empty POST 2002-10-02 13:20 klacke * src/yaws_api.erl: bad export 2002-10-01 20:53 jbevemyr * applications/wiki/src/wiki.erl, applications/wiki/src/wiki_yaws.erl, src/yaws_server.erl: Fixed problem with file uploads 2002-10-01 20:35 jbevemyr * applications/wiki/wiki/allRefsToMe.yaws: [no log message] 2002-09-27 14:46 klacke * scripts/yaws.init.d: readded jb's chkconfig comment 2002-09-27 14:39 klacke * vsn.mk, www/dynamic.yaws: "" 2002-09-27 14:20 klacke * man/yaws_api.5: [no log message] 2002-09-27 14:16 klacke * scripts/yaws.init.d: "" 2002-09-27 13:05 klacke * applications/webmail/test.erl: "" 2002-09-27 13:03 klacke * applications/webmail/test.erl, man/yaws_api.5, src/yaws.erl, src/yaws_api.erl, src/yaws_config.erl, src/yaws_ctl.erl, src/yaws_server.erl, www/configuration.yaws: added support/docs for embedded mode 2002-09-26 15:08 klacke * man/Makefile: "" 2002-09-25 22:44 etnt * src/Makefile: Now, tar also works on FreeBSD. 2002-09-22 22:06 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_templates.erl, wiki/allpages.gif, wiki/editfiles.gif, wiki/editme.gif, wiki/history.gif, wiki/home.gif, wiki/lastedited.gif, wiki/zombies.gif, wiki/custom.css: Some look and feel enhancements 2002-09-20 22:10 jbevemyr * applications/wiki/: src/wiki_format_txt.erl, src/wiki_to_html.erl, wiki/FormattingWikiPages.wob: Fixed editTag bug and added embedded HTML support 2002-09-18 22:26 jbevemyr * applications/wiki/src/wiki.erl, applications/wiki/src/wiki_yaws.erl, applications/wiki/wiki/addFile.yaws, applications/wiki/wiki/allPages.yaws, applications/wiki/wiki/allRefsToMe.yaws, applications/wiki/wiki/copyFiles.yaws, applications/wiki/wiki/createNewPage.yaws, applications/wiki/wiki/deleteFiles.yaws, applications/wiki/wiki/deletePage.yaws, applications/wiki/wiki/editFiles.yaws, applications/wiki/wiki/editPage.yaws, applications/wiki/wiki/editTag.yaws, applications/wiki/wiki/finalDeletePage.yaws, applications/wiki/wiki/getFile.yaws, applications/wiki/wiki/importFiles.yaws, applications/wiki/wiki/lastEdited.yaws, applications/wiki/wiki/previewNewPage.yaws, applications/wiki/wiki/previewPage.yaws, applications/wiki/wiki/previewTagged.yaws, applications/wiki/wiki/putPassword.yaws, applications/wiki/wiki/sendMeThePassword.yaws, applications/wiki/wiki/showHistory.yaws, applications/wiki/wiki/showOldPage.yaws, applications/wiki/wiki/showPage.yaws, applications/wiki/wiki/storeFiles.yaws, applications/wiki/wiki/storeNewPage.yaws, applications/wiki/wiki/storePage.yaws, applications/wiki/wiki/storeTagged.yaws, applications/wiki/wiki/wikiZombies.yaws, src/yaws_server.erl: Added full argument chunking support in Wiki 2002-09-18 01:15 klacke * include/yaws_api.hrl, src/Makefile, src/yaws_api.erl, src/yaws_config.erl, src/yaws_server.erl, src/yaws_session_server.erl, src/yaws_sup.erl, www/api.yaws: cache_refresh to 0 if debug, added a cookie_session-server for persistant cookie sessions 2002-09-18 01:05 klacke * man/yaws_api.5: documented yaws_api 2002-09-17 23:27 klacke * man/yaws.conf.5: documented auth and some other config opts 2002-09-17 21:46 klacke * src/yaws_server.erl: fixed bug in jb's implementation of chunking large files 2002-09-17 21:44 klacke * src/: yaws_compile.erl, yaws_ctl.erl, yaws_server.erl: a file which has at least one compilation error shouldn't be cached in the code cache, the nect time the same file is GET'ed it a recompilation is attempted 2002-09-16 23:55 jbevemyr * src/: yaws.hrl, yaws_server.erl: [no log message] 2002-09-16 23:36 jbevemyr * src/yaws_server.erl: Fixed broken sending of files > 1000000 bytes. Added support for sending very large files by chunking. 2002-09-16 19:05 klacke * src/: yaws.erl, yaws_api.erl: "" 2002-09-15 19:40 klacke * src/yaws_api.erl: "" 2002-09-15 17:04 klacke * src/yaws_api.erl: api:parse_query/1 2002-09-14 01:20 klacke * src/yaws_server.erl: minor bug in streamed content 2002-09-13 17:22 klacke * include/yaws_api.hrl, src/yaws.erl, src/yaws_server.erl: support for streamed large content from yaws code 2002-09-12 17:26 klacke * src/yaws_ctl.erl: multiple user by uid can now run yaws 2002-09-12 17:25 klacke * src/: yaws.hrl, yaws_compile.erl, yaws_config.erl, yaws_ctl.erl, yaws_server.erl: javascript support in ehtml 2002-09-12 04:51 lukeg * ChangeLog: [no log message] 2002-09-12 04:22 lukeg * src/yaws_api.erl: Exported htmlize_char/1 2002-09-12 04:21 lukeg * src/yaws_server.erl: Removed url_decode in get_path/1 - it is too early, causes problems if it unescapes &'s in the query string. Has to wait until the query is parsed (and it looks like yaws_api:do_parse_spec does it for us already) For redirects, using 302 for HTTP 1.0 browsers because they don't understand 303. This change is small but noisy since I had to pass another arg to handle_out_reply (many clauses). Added an {ehtml, ...} return type for out/1 functions. It does very basic tuple->HTML expansions. Chunked encoding: skip accumulating 0-length chunks, e.g. when out/1 returns an empty result, because they look like terminators. 2002-09-10 00:03 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_templates.erl, wiki/addFile.yaws, wiki/allPages.yaws, wiki/allRefsToMe.yaws, wiki/copyFiles.yaws, wiki/createNewPage.yaws, wiki/deleteFiles.yaws, wiki/deletePage.yaws, wiki/editFiles.yaws, wiki/editPage.yaws, wiki/editTag.yaws, wiki/finalDeletePage.yaws, wiki/importFiles.yaws, wiki/lastEdited.yaws, wiki/previewNewPage.yaws, wiki/previewPage.yaws, wiki/previewTagged.yaws, wiki/putPassword.yaws, wiki/sendMeThePassword.yaws, wiki/showHistory.yaws, wiki/showOldPage.yaws, wiki/showPage.yaws, wiki/storeFiles.yaws, wiki/storeNewPage.yaws, wiki/storePage.yaws, wiki/storeTagged.yaws, wiki/wikiZombies.yaws: w3c compliant html code 2002-09-09 23:06 uid50986 * src/yaws_server.erl: added new break ret val from out/1 function 2002-09-09 10:09 jbevemyr * scripts/yaws.init.d: Added chkconfig support to init.d file 2002-09-06 09:18 jbevemyr * applications/wiki/src/: wiki.erl, wiki_templates.erl: Minor modifications to the HTML templates 2002-09-03 01:04 jbevemyr * applications/wiki/src/wiki.erl: Some more interface improvements 2002-09-03 00:32 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_to_html.erl, src/wiki_yaws.erl, wiki/addFile.yaws, wiki/copyFiles.yaws, wiki/deleteFiles.yaws, wiki/putPassword.yaws: improved file editing interface 2002-09-02 23:10 klacke * www/index.yaws: "" 2002-09-02 22:58 klacke * ChangeLog: auto generated changelog 2002-09-02 22:26 klacke * src/yaws_api.erl, www/readpcookie.yaws: "" 2002-09-02 21:44 klacke * src/mime.types: "" 2002-09-02 21:37 klacke * vsn.mk, applications/webmail/Makefile, src/Makefile: [no log message] 2002-09-02 20:54 klacke * LICENSE, applications/webmail/TOP, applications/webmail/att.yaws, applications/webmail/compose.yaws, applications/webmail/index.yaws, applications/webmail/logout.yaws, applications/webmail/mstil.css, applications/webmail/read_mail.yaws, applications/webmail/rmail.yaws, applications/webmail/test.erl, applications/webmail/webmail.erl, applications/webmail/webmail.hrl, applications/webmail/webmail_login.yaws, applications/webmail/webmail_login_post.yaws, src/Makefile, src/mime_type_c.erl, src/yaws_api.erl, src/yaws_server.erl, src/yaws_ssl.erl: "" 2002-09-01 21:14 jbevemyr * applications/wiki/: src/Makefile, src/wiki.erl, src/wiki_templates.erl, src/wiki_to_html.erl, wiki/importFiles.yaws: Improved files interface 2002-09-01 21:14 jbevemyr * src/yaws_server.erl: Added support for OPTIONS http request 2002-08-26 12:32 jbevemyr * applications/wiki/: src/wiki.erl, src/wiki_yaws.erl, wiki/allPages.yaws, wiki/allRefsToMe.yaws, wiki/createNewPage.yaws, wiki/deletePage.yaws, wiki/editFiles.yaws, wiki/editPage.yaws, wiki/editTag.yaws, wiki/finalDeletePage.yaws, wiki/getFile.yaws, wiki/lastEdited.yaws, wiki/previewNewPage.yaws, wiki/previewPage.yaws, wiki/previewTagged.yaws, wiki/sendMeThePassword.yaws, wiki/showHistory.yaws, wiki/showOldPage.yaws, wiki/showPage.yaws, wiki/storeFiles.yaws, wiki/storeNewPage.yaws, wiki/storePage.yaws, wiki/storeTagged.yaws, wiki/wikiZombies.yaws: Ported to new parse_post_data api 2002-08-26 11:26 jbevemyr * src/yaws_api.erl: Added some documentation 2002-08-26 11:25 jbevemyr * src/yaws_server.erl: Fixed probem with using parse_post_data for multipart posts when partial_post_size is not set 2002-08-24 00:44 seanhinde * include/yaws_api.hrl: added cont and state to this yaws_api.hrl 2002-08-24 00:34 seanhinde * src/yaws.hrl: tidy up merge slightly 2002-08-24 00:26 seanhinde * src/: yaws.hrl, yaws_api.erl, yaws_config.erl, yaws_server.erl: Changed implementation of multipart form data. There is a new config parameter called partial_post_size which if set to an integer value will cause the content of the post content to be sent to the out/1 function in chunks of this size. Changed implementation of multipart form data. There is a new config parameter called partial_post_size which if set to an integer value will cause the content of the post content to be sent to the out/1 function in chunks of this size. It is possible to get the server to maintain a state on behalf of the out/1 user by returning {get_more, Cont, State}. yaws_api:parse_post_data/1 will return either: {cont, Cont, Res} where Res is new result(s) from this segment. This indicates that there is more data to come and the out/1 function should return {get_more, Cont, User_state} where User_state might usefully be a File Descriptor. Changed implementation of multipart form data. There is a new config parameter called partial_post_size which if set to an integer value will cause the content of the post content to be sent to the out/1 function in chunks of this size. It is possible to get the server to maintain a state on behalf of the out/1 user by returning {get_more, Cont, State}. yaws_api:parse_post_data/1 will now return either: {cont, Cont, Res} where Res is new result(s) from this segment. This indicates that there is more data to come and the out/1 function should return {get_more, Cont, User_state} where User_state might usefully be a File Descriptor. or {result, Res} if this is the last (or only) segment. Res is a list of {header, Header} | {part_body, Binary} | {body, Binary} Example usage could be: <erl> out(A) -> case yaws_api:parse_post_data(A) of {cont, Cont, Res} -> St = handle_res(A, Res), {get_more, Cont, St}; {result, Res} -> handle_res(A, Res), {html, f("<pre>Done </pre>",[])} end. handle_res(A, [{head, Name}|T]) -> io:format("head:~p~n",[Name]), handle_res(A, T); handle_res(A, [{part_body, Data}|T]) -> io:format("part_body:~p~n",[Data]), handle_res(A, T); handle_res(A, [{body, Data}|T]) -> io:format("body:~p~n",[Data]), handle_res(A, T); handle_res(A, []) -> io:format("End_res~n"). </erl> 2002-08-22 18:04 jbevemyr * src/yaws_api.erl: Added a third parameter to the tuples returned by parse_post_data when parsing multipart/form-data. This third argument contains the options from the content-disposition header. 2002-08-22 18:02 jbevemyr * applications/wiki/: README, src/wiki.erl: Remove the explicit matching of options and improved the file upload interface. 2002-08-21 12:50 jbevemyr * applications/wiki/: include.mk, src/wiki.erl, src/wiki_to_html.erl: minor fixes 2002-08-20 22:25 klacke * src/Makefile: new make target for joe 2002-08-20 22:25 klacke * src/yaws_config.erl: didn't compile 2002-08-05 16:38 seanhinde * scripts/yaws.conf.basic_auth, src/yaws.hrl, src/yaws_config.erl, src/yaws_server.erl: Added Basic Authentication support with a new subsection to the server config <auth> .. </auth>. Attributes valid in the subsection are dir = /path/to/secure/pages (can have more than one), realm = Text, where Text is presented to the user in the password dialog, and user = username:passwd (can have more than one). This is not perfect yet, url_type/3 does more than just decode the url.. but it is a step. An example of the new config is in the file yaws.conf.basic_auth in the scripts dir 2002-07-19 18:18 mikl * CHANGELOG, applications/wiki/src/wiki.erl: Bugfix: Function clause error fixed when the number of HTTP parameters for wiki:editPage/3 is different from 1 or 3 2002-07-19 17:58 mikl * CHANGELOG, applications/wiki/src/wiki_to_html.erl, applications/wiki/wiki/editTag.yaws: Wiki: Added the editTag page, that prevented to edit feedback area 2002-07-19 17:47 mikl * applications/wiki/ebin/.keepme: Added a .keepme file in wiki ebin, to be sure the dir is checked out with cvs -PAd 2002-07-05 10:29 jbevemyr * src/: yaws_api.erl, yaws_server.erl: Added support for IE-style URL encoding 2002-07-03 23:57 klacke * vsn.mk: [no log message] 2002-07-02 22:26 jbevemyr * applications/wiki/src/wiki.erl: [no log message] 2002-07-01 22:30 klacke * www/index.yaws: "" 2002-07-01 22:18 klacke * Makefile, vsn.mk, applications/webmail/HEAD, applications/webmail/Makefile, applications/webmail/TOP, applications/webmail/blurulr3.gif, applications/webmail/blurulr4.gif, applications/webmail/index.yaws, applications/webmail/mail.gif, applications/webmail/mstil.css, applications/webmail/webmail.erl, applications/webmail/webmail.hrl, applications/webmail/webmail_login.yaws, applications/webmail/webmail_login_post.yaws, applications/webmail/ylwmail.gif, scripts/Makefile, src/yaws_server.erl, www/todo.yaws, www/testdir/index.html: "" 2002-06-28 00:46 jbevemyr * www/: dynamic.yaws, history.yaws: Documented new features 2002-06-28 00:45 jbevemyr * src/: yaws_api.erl, yaws_server.erl: Fixed 303 host:port bug. Added yaws_api:url_decode to get_path/1. Added {redirect_local,Path} and {redirect, Url} as possible return values to out/1. Added fullpath element to arg record. 2002-06-28 00:44 jbevemyr * scripts/yaws.ss: Fixed heart bug 2002-06-28 00:43 jbevemyr * include/yaws_api.hrl: Added fullpath to arg 2002-06-28 00:40 jbevemyr * applications/wiki/: Makefile, README, include.mk, vsn.mk, src/Makefile, src/wiki.erl, src/wiki_diff.erl, src/wiki_format_txt.erl, src/wiki_split.erl, src/wiki_templates.erl, src/wiki_to_html.erl, src/wiki_utils.erl, src/wiki_vsn.template, src/wiki_yaws.erl, wiki/ALockedPage.wob, wiki/AnUnlockedPage.wob, wiki/Examples.wob, wiki/FormattingWikiPages.wob, wiki/allPages.yaws, wiki/allRefsToMe.yaws, wiki/allpages.gif, wiki/createNewPage.yaws, wiki/deletePage.yaws, wiki/edit.gif, wiki/editFiles.yaws, wiki/editPage.yaws, wiki/editfiles.gif, wiki/editme.gif, wiki/finalDeletePage.yaws, wiki/getFile.yaws, wiki/history.gif, wiki/home.gif, wiki/icon.gif, wiki/index.yaws, wiki/info.gif, wiki/lastEdited.yaws, wiki/lastedited.gif, wiki/locked.gif, wiki/normal.gif, wiki/old.gif, wiki/previewNewPage.yaws, wiki/previewPage.yaws, wiki/previewTagged.yaws, wiki/sendMeThePassword.yaws, wiki/showHistory.yaws, wiki/showOldPage.yaws, wiki/showPage.yaws, wiki/storeFiles.yaws, wiki/storeNewPage.yaws, wiki/storePage.yaws, wiki/storeTagged.yaws, wiki/wikiZombies.yaws, wiki/zombies.gif: Added Joe's Wiki code 2002-06-27 10:06 jbevemyr * www/query.yaws: Fixed link to point to local instance 2002-06-20 14:18 etnt * man/yaws.1: Added the -heart switch 2002-06-20 14:14 etnt * scripts/yaws.ss: Added support for the '-heart' switch. 2002-06-20 12:11 jbevemyr * www/man.yaws: Added illegal character check to input to man page command to stop cracking 2002-06-19 23:37 etnt * scripts/yaws.ss: Added the '-sname <Node>' switch to the yaws script 2002-06-19 17:02 jbevemyr * src/yaws_api.erl: pre_ssi_string now use list version of htmlize since the binary version craches for large strings, eg man less 2002-06-19 15:45 jbevemyr * src/yaws_server.erl: [no log message] 2002-06-19 15:02 klacke * man/yaws.1, www/index.yaws: "" 2002-06-19 14:50 klacke * src/yaws_config.erl, src/yaws_log.erl, src/yaws_server.erl, www/dynamic.yaws, www/history.yaws, www/index.yaws: "" 2002-06-19 13:30 jbevemyr * src/yaws_server.erl: code:purge added for old modules 2002-06-19 12:59 jbevemyr * src/yaws_api.erl, www/api.yaws, www/history.yaws, www/man.yaws, www/post.yaws, www/query.yaws: Updated parse_post_data api to support multiline post data 2002-06-19 00:53 jbevemyr * include.mk: [no log message] 2002-06-19 00:50 jbevemyr * include.mk, src/yaws_api.erl: Added support for multipart post data. Added parse_post api function. 2002-06-18 16:45 klacke * scripts/Makefile: "" 2002-06-18 16:33 klacke * README, vsn.mk, man/yaws.conf.5, src/yaws.hrl, src/yaws_config.erl, src/yaws_ls.erl, src/yaws_server.erl, www/history.yaws: "" 2002-06-18 13:10 klacke * src/yaws_server.erl, www/api.yaws, www/configuration.yaws, www/dynamic.yaws, www/history.yaws, www/index.yaws, www/motivation.yaws, www/setcookie.yaws, www/setpcookie.yaws, www/simple.yaws, www/shopingcart/cart.yaws, www/testdir/index.html: "" 2002-06-17 22:58 klacke * www/testdir/: index.html, xxåäöxx.jpg: "" 2002-06-17 22:48 klacke * www/: EXHEAD, index.yaws, query.yaws: "" 2002-06-17 14:26 etnt * man/yaws.1, scripts/yaws.ss, src/yaws_server.erl: Added the '-r <Mod>' switch. 2002-06-17 14:16 etnt * README: Testing CVS commit. 2002-06-17 14:12 etnt * Makefile: "" 2002-06-16 23:05 klacke * scripts/yaws.init.d: "" 2002-06-16 22:55 klacke * www/index.yaws: "" 2002-06-16 22:51 klacke * vsn.mk, man/yaws.1, scripts/yaws.ss, src/yaws_api.erl, src/yaws_server.erl, www/history.yaws: "" 2002-06-16 17:00 klacke * Makefile, include.mk, scripts/Install, scripts/yaws.ss, src/yaws_api.erl, src/yaws_ctl.erl, src/yaws_debug.erl, src/yaws_server.erl, www/configuration.yaws, www/history.yaws, www/man.yaws, www/stil.css: "" 2002-06-15 12:51 klacke * vsn.mk, www/history.yaws: "" 2002-06-15 12:24 klacke * man/yaws.conf.5, src/yaws.hrl, src/yaws_compile.erl, src/yaws_config.erl, src/yaws_server.erl, www/small.yaws, www/static.html, src/yaws_compile.erl: "" 2002-06-14 15:27 klacke * applications/webmail/: Makefile, smtp_client.erl: "" 2002-06-14 13:33 klacke * applications/webmail/: pop3lib_cli.erl, smtp_client.erl: "" 2002-06-14 10:02 klacke * src/Makefile, src/yaws_api.erl, src/yaws_server.erl, www/EXHEAD, www/todo.yaws, www/shopingcart/cart.yaws, www/shopingcart/mall.yaws: "" 2002-06-13 13:55 klacke * www/stats.yaws: "" 2002-06-13 12:35 klacke * Makefile, vsn.mk, man/Makefile, man/yaws.1, man/yaws.conf.5, scripts/yaws.conf.template, scripts/yaws.conf.template.local, scripts/yaws.ss, src/yaws.erl, src/yaws_config.erl, www/configuration.yaws, www/dynamic.yaws, www/history.yaws, www/index.yaws: "" 2002-06-12 17:40 klacke * vsn.mk, src/yaws.hrl, src/yaws_api.erl, src/yaws_compile.erl, src/yaws_ls.erl, src/yaws_server.erl, www/api.yaws, www/dynamic.yaws, www/history.yaws, www/index.yaws, www/post.yaws, www/readcookie.yaws, www/readpcookie.yaws, www/redirect.yaws, www/redirect2.yaws, www/setcookie.yaws, www/setpcookie.yaws, www/simple_ex2.yaws, www/simple_ex3.yaws, www/small.yaws: new ret vals from out/1 2002-06-11 15:46 klacke * vsn.mk, src/yaws.erl, src/yaws_server.erl, www/history.yaws: "" 2002-06-11 11:23 klacke * src/yaws_server.erl: "" 2002-06-11 11:18 klacke * src/yaws_server.erl: "" 2002-06-11 01:28 klacke * src/: Makefile, yaws.erl, yaws_compile.erl, yaws_debug.erl, yaws_server.erl, yaws_ssl.erl: "" 2002-06-10 23:35 klacke * vsn.mk, ebin/.empty, ebin/erl_crash.dump, ebin/ewww.app, ebin/yaws.app, src/yaws_api.erl, src/yaws_config.erl, src/yaws_ls.erl, src/yaws_server.erl, www/history.yaws, www/post.yaws, www/static.html, www/todo.yaws: "" 2002-06-10 18:48 klacke * scripts/make-upload: "" 2002-06-10 18:30 klacke * scripts/make-upload: "" 2002-06-10 18:01 klacke * LICENSE, Makefile, vsn.mk, ebin/yaws.app, scripts/Makefile, src/Makefile, src/yaws.erl, src/yaws_server.erl, src/yaws_vsn.template, www/static.html: "" 2002-06-03 15:16 klacke * src/yaws_server.erl, vsn.mk: "" 2002-06-03 14:44 klacke * scripts/make-release, src/yaws_server.erl: "" 2002-06-03 12:57 klacke * src/yaws_ls.erl, www/index.yaws: "" 2002-05-30 13:09 klacke * vsn.mk, ebin/yaws.app, src/yaws_server.erl, www/configuration.yaws, www/history.yaws, www/index.yaws, www/todo.yaws: "" 2002-05-30 11:09 klacke * src/: yaws.erl, yaws_api.erl, yaws_app.erl, yaws_compile.erl, yaws_config.erl, yaws_ctl.erl, yaws_debug.erl, yaws_log.erl, yaws_ls.erl, yaws_server.erl, yaws_ssl.erl: "" 2002-05-30 10:13 klacke * src/yaws_ssl.erl: "" 2002-05-30 00:28 klacke * src/yaws_server.erl: "" 2002-05-29 23:54 klacke * ebin/yaws.app, src/Makefile, src/yaws.erl, src/yaws.hrl, src/yaws_config.erl, src/yaws_server.erl, ssl/cert.example, ssl/key.example, www/todo.yaws: "" 2002-04-30 11:36 klacke * ebin/yaws.app, scripts/make-release, src/yaws_server.erl: "" 2002-04-30 11:07 klacke * src/yaws_server.erl: "" 2002-04-30 10:51 klacke * vsn.mk: "" 2002-04-30 10:43 klacke * ebin/yaws.app, include/yaws_api.hrl, scripts/yaws.ss, src/Makefile, src/yaws.erl, src/yaws_ctl.erl, src/yaws_ls.erl, src/yaws_server.erl, README: "" 2002-04-20 01:22 klacke * ebin/yaws.app, include/yaws_api.hrl, src/yaws_server.erl, www/todo.yaws: "" 2002-03-29 17:52 klacke * src/yaws_log.erl, vsn.mk, www/history.yaws: "" 2002-03-28 11:51 klacke * src/: Makefile, yaws.erl, yaws.hrl, yaws_config.erl, yaws_server.erl: "" 2002-03-27 12:21 klacke * ebin/yaws.app, src/yaws_server.erl, www/dynamic.yaws: "" 2002-03-26 18:46 klacke * scripts/make-release: "" 2002-03-26 18:42 klacke * src/yaws_server.erl: "" 2002-03-26 18:31 klacke * vsn.mk, src/yaws.erl, src/yaws_log.erl, src/yaws_server.erl, www/history.yaws: "" 2002-03-26 12:58 klacke * src/yaws_server.erl: "" 2002-03-24 13:27 klacke * src/yaws_compile.erl: "" 2002-03-21 16:30 klacke * www/stil.css: "" 2002-03-17 12:22 klacke * ebin/yaws.app, scripts/yaws.ss, src/yaws_log.erl, src/yaws_server.erl, www/history.yaws: "" 2002-03-08 21:15 klacke * www/configuration.yaws: "" 2002-03-08 21:01 klacke * vsn.mk, ebin/yaws.app, src/yaws_config.erl: "" 2002-03-04 22:51 klacke * vsn.mk, ebin/yaws.app, src/yaws_ls.erl, www/history.yaws: "" 2002-03-04 22:23 klacke * vsn.mk, ebin/yaws.app, scripts/Install, src/yaws_config.erl, src/yaws_log.erl: "" 2002-03-04 22:03 klacke * vsn.mk, ebin/yaws.app, scripts/Install, scripts/Makefile: "" 2002-03-04 21:32 klacke * vsn.mk, scripts/Makefile: "" 2002-03-04 21:26 klacke * vsn.mk, bin/.foobar, scripts/Makefile, scripts/make-release, www/history.yaws, vsn.mk, scripts/make-release: "" 2002-03-04 20:29 klacke * Makefile, vsn.mk, scripts/make-release: "" 2002-03-04 19:30 klacke * www/shopingcart/cart.yaws, www/shopingcart/junk.jpg, www/shopingcart/mall.yaws, Makefile, README, vsn.mk, ebin/yaws.app, scripts/Makefile, scripts/yaws.ss, src/yaws.erl, src/yaws.hrl, src/yaws_api.erl, src/yaws_compile.erl, src/yaws_config.erl, src/yaws_debug.erl, src/yaws_log.erl, src/yaws_server.erl, www/EXHEAD, www/TOPTAB, www/api.yaws, www/configuration.yaws, www/examples.yaws, www/history.yaws, www/index.yaws, www/pcookie.yaws, www/readcookie.yaws, www/readpcookie.yaws, www/setcookie.yaws, www/setpcookie.yaws, www/simple.yaws, www/stil.css, www/todo.yaws, www/contact.yaws, www/simple_ex3.yaws, www/stats_ex.yaws: "" 2002-02-25 21:50 klacke * Makefile, ebin/yaws.app, include/yaws_api.hrl, src/Makefile, src/yaws.erl, src/yaws.hrl, src/yaws_api.erl, src/yaws_compile.erl, src/yaws_config.erl, src/yaws_server.erl, www/EXHEAD, www/HEAD, www/TOPTAB, www/api.yaws, www/cookies.yaws, www/dynamic.yaws, www/examples.yaws, www/history.yaws, www/index.yaws, www/pcookie.yaws, www/readcookie.yaws, www/readpcookie.yaws, www/setcookie.yaws, www/setpcookie.yaws, www/simple.yaws, www/stil.css: "" 2002-02-24 10:46 klacke * www/history.yaws: "" 2002-02-20 16:46 klacke * ebin/yaws.app, scripts/yaws.conf.template, src/yaws_api.erl, src/yaws_server.erl, www/END, www/EXHEAD, www/HEAD, www/TOPTAB, www/cookies.yaws, www/examples.yaws, www/form.yaws, www/index.yaws, www/post.yaws, www/setcookie.yaws, www/simple.yaws, www/stats.yaws, www/stil.css, www/todo.yaws: "" 2002-02-18 11:45 lukeg * src/yaws_server.erl: Bugfix s/yaws:format_ip/yaws:fmt_ip/ 2002-02-13 21:41 klacke * vsn.mk: "" 2002-02-13 21:37 klacke * www/TOPTAB: "" 2002-02-13 21:33 klacke * src/yaws_server.erl, www/EXHEAD, www/HEAD, www/TOPTAB, www/index.yaws: "" 2002-02-13 19:39 klacke * bin/yaws, src/yaws_server.erl, www/TOPTAB, www/index.yaws, bin/yaws: "" 2002-02-13 09:15 klacke * src/yaws_api.erl, src/yaws_server.erl, www/END, www/stats.yaws: "" 2002-02-12 14:19 klacke * src/yaws_api.erl, www/EXHEAD, www/TOPTAB, www/configuration.yaws, www/dynamic.yaws, www/examples.yaws, www/index.html, www/index.yaws, www/motivation.yaws, www/todo.yaws, www/top.yaws: "" 2002-02-12 12:21 klacke * bin/yaws, scripts/Makefile, scripts/yaws.conf.template.local, scripts/yaws.ss, src/yaws_log.erl, src/yaws_server.erl, www/EXHEAD, www/HEAD, www/TOPTAB, www/index.html, www/todo.yaws: "" 2002-02-12 01:55 klacke * Makefile, vsn.mk, www/index.yaws, www/todo.yaws: "" 2002-02-12 01:15 klacke * Makefile, include.mk, include.mk.in, bin/yaws, ebin/yaws.beam, ebin/yaws_api.beam, ebin/yaws_app.beam, ebin/yaws_config.beam, ebin/yaws_debug.beam, ebin/yaws_log.beam, ebin/yaws_ls.beam, ebin/yaws_server.beam, ebin/yaws_sup.beam, scripts/Makefile, scripts/mangle, scripts/yaws.conf.template, scripts/yaws.ss, sourceforge-site/index.html, sourceforge-site/yaws_head3.gif, sourceforge-site/yaws_pb2.gif, src/Makefile, src/yaws.hrl, src/yaws_config.erl, src/yaws_server.erl, www/HEAD, www/index.yaws, www/todo.yaws, ebin/bassert.beam, ebin/ewww.beam, ebin/ewww_app.beam, ebin/ewww_config.beam, ebin/ewww_server.beam, ebin/ewww_sup.beam, ebin/yaws.beam, ebin/yaws_api.beam, ebin/yaws_app.beam, ebin/yaws_config.beam, ebin/yaws_debug.beam, ebin/yaws_log.beam, ebin/yaws_ls.beam, ebin/yaws_server.beam, ebin/yaws_sup.beam: "" 2002-02-11 17:53 klacke * src/yaws_server.erl: "" 2002-02-11 17:19 klacke * Makefile, include.mk, include.mk.in, vsn.mk, src/Makefile, src/yaws.app.src, src/yaws.conf, src/yaws.hrl, src/yaws_app.erl, src/yaws_ls.erl, src/yaws_sup.erl, ebin/bassert.beam, ebin/ewww.app, ebin/ewww.beam, ebin/ewww_app.beam, ebin/ewww_config.beam, ebin/ewww_server.beam, ebin/ewww_sup.beam, ebin/yaws.app, ebin/yaws.beam, src/yaws.erl, src/yaws_api.erl, src/yaws_config.erl, src/yaws_debug.erl, src/yaws_debug.hrl, src/yaws_log.erl, src/yaws_server.erl, ebin/erl_crash.dump, ebin/yaws_api.beam, ebin/yaws_app.beam, ebin/yaws_config.beam, ebin/yaws_debug.beam, ebin/yaws_log.beam, ebin/yaws_ls.beam, ebin/yaws_server.beam, ebin/yaws_sup.beam, include/yaws_api.hrl, priv/mime.types, www/HEAD, www/TOPTAB, www/form.yaws, www/index.html, www/index.yaws, www/motivation.yaws, www/post.yaws, www/spacer.gif, www/todo.yaws, www/top.yaws, www/EXHEAD, www/configuration.yaws, www/dynamic.yaws, www/examples.yaws, www/simple.yaws, www/simple_ex1.yaws, www/simple_ex2.yaws, www/.xvpics/hyber.org.gif, www/.xvpics/hyber_org.jpg, www/icons/PythonPowered.png, www/icons/README, www/icons/a.gif, www/icons/alert.black.gif, www/icons/alert.red.gif, www/icons/apache_pb.gif, www/icons/back.gif, www/icons/ball.gray.gif, www/icons/ball.red.gif, www/icons/binary.gif, www/icons/binhex.gif, www/icons/blank.gif, www/icons/bomb.gif, www/icons/box1.gif, www/icons/box2.gif, www/icons/broken.gif, www/icons/burst.gif, www/icons/c.gif, www/icons/comp.blue.gif, www/icons/comp.gray.gif, www/icons/compressed.gif, www/icons/continued.gif, www/icons/dir.gif, www/icons/down.gif, www/icons/dvi.gif, www/icons/erl.gif, www/icons/f.gif, www/icons/folder.gif, www/icons/folder.open.gif, www/icons/folder.sec.gif, www/icons/forward.gif, www/icons/generic.gif, www/icons/generic.red.gif, www/icons/generic.sec.gif, www/icons/gnu-head-tiny.jpg, www/icons/hand.right.gif, www/icons/hand.up.gif, www/icons/hrl.gif, www/icons/icon.sheet.gif, www/icons/image1.gif, www/icons/image2.gif, www/icons/image3.gif, www/icons/index.gif, www/icons/layout.gif, www/icons/left.gif, www/icons/link.gif, www/icons/mailman-large.jpg, www/icons/mailman.jpg, www/icons/movie.gif, www/icons/p.gif, www/icons/patch.gif, www/icons/pdf.gif, www/icons/php4.gif, www/icons/pie0.gif, www/icons/pie1.gif, www/icons/pie2.gif, www/icons/pie3.gif, www/icons/pie4.gif, www/icons/pie5.gif, www/icons/pie6.gif, www/icons/pie7.gif, www/icons/pie8.gif, www/icons/portal.gif, www/icons/ps.gif, www/icons/quill.gif, www/icons/right.gif, www/icons/screw1.gif, www/icons/screw2.gif, www/icons/script.gif, www/icons/sound1.gif, www/icons/sound2.gif, www/icons/sphere1.gif, www/icons/sphere2.gif, www/icons/tar.gif, www/icons/tex.gif, www/icons/text.gif, www/icons/transfer.gif, www/icons/unknown.gif, www/icons/up.gif, www/icons/uu.gif, www/icons/uuencoded.gif, www/icons/world1.gif, www/icons/world2.gif, www/icons/yaws.gif, www/icons/yawsY.gif, www/icons/yaws_head.gif, www/icons/yaws_pb.gif, www/icons/small/README.txt, www/icons/small/back.gif, www/icons/small/binary.gif, www/icons/small/binhex.gif, www/icons/small/blank.gif, www/icons/small/broken.gif, www/icons/small/burst.gif, www/icons/small/comp1.gif, www/icons/small/comp2.gif, www/icons/small/compressed.gif, www/icons/small/continued.gif, www/icons/small/dir.gif, www/icons/small/dir2.gif, www/icons/small/doc.gif, www/icons/small/forward.gif, www/icons/small/generic.gif, www/icons/small/generic2.gif, www/icons/small/generic3.gif, www/icons/small/image.gif, www/icons/small/image2.gif, www/icons/small/index.gif, www/icons/small/key.gif, www/icons/small/movie.gif, www/icons/small/patch.gif, www/icons/small/ps.gif, bin/yaws, scripts/Makefile, scripts/mangle, scripts/yaws.conf, scripts/yaws.conf.template, scripts/yaws.ss, www/icons/small/rainbow.gif, www/icons/small/sound.gif, www/icons/small/sound2.gif, www/icons/small/tar.gif, www/icons/small/text.gif, www/icons/small/transfer.gif, www/icons/small/unknown.gif, www/icons/small/uu.gif: first time import 2002-02-11 17:19 klacke * Makefile, include.mk, include.mk.in, vsn.mk, src/Makefile, src/yaws.app.src, src/yaws.conf, src/yaws.hrl, src/yaws_app.erl, src/yaws_ls.erl, src/yaws_sup.erl, ebin/bassert.beam, ebin/ewww.app, ebin/ewww.beam, ebin/ewww_app.beam, ebin/ewww_config.beam, ebin/ewww_server.beam, ebin/ewww_sup.beam, ebin/yaws.app, ebin/yaws.beam, src/yaws.erl, src/yaws_api.erl, src/yaws_config.erl, src/yaws_debug.erl, src/yaws_debug.hrl, src/yaws_log.erl, src/yaws_server.erl, ebin/erl_crash.dump, ebin/yaws_api.beam, ebin/yaws_app.beam, ebin/yaws_config.beam, ebin/yaws_debug.beam, ebin/yaws_log.beam, ebin/yaws_ls.beam, ebin/yaws_server.beam, ebin/yaws_sup.beam, include/yaws_api.hrl, priv/mime.types, www/HEAD, www/TOPTAB, www/form.yaws, www/index.html, www/index.yaws, www/motivation.yaws, www/post.yaws, www/spacer.gif, www/todo.yaws, www/top.yaws, www/EXHEAD, www/configuration.yaws, www/dynamic.yaws, www/examples.yaws, www/simple.yaws, www/simple_ex1.yaws, www/simple_ex2.yaws, www/.xvpics/hyber.org.gif, www/.xvpics/hyber_org.jpg, www/icons/PythonPowered.png, www/icons/README, www/icons/a.gif, www/icons/alert.black.gif, www/icons/alert.red.gif, www/icons/apache_pb.gif, www/icons/back.gif, www/icons/ball.gray.gif, www/icons/ball.red.gif, www/icons/binary.gif, www/icons/binhex.gif, www/icons/blank.gif, www/icons/bomb.gif, www/icons/box1.gif, www/icons/box2.gif, www/icons/broken.gif, www/icons/burst.gif, www/icons/c.gif, www/icons/comp.blue.gif, www/icons/comp.gray.gif, www/icons/compressed.gif, www/icons/continued.gif, www/icons/dir.gif, www/icons/down.gif, www/icons/dvi.gif, www/icons/erl.gif, www/icons/f.gif, www/icons/folder.gif, www/icons/folder.open.gif, www/icons/folder.sec.gif, www/icons/forward.gif, www/icons/generic.gif, www/icons/generic.red.gif, www/icons/generic.sec.gif, www/icons/gnu-head-tiny.jpg, www/icons/hand.right.gif, www/icons/hand.up.gif, www/icons/hrl.gif, www/icons/icon.sheet.gif, www/icons/image1.gif, www/icons/image2.gif, www/icons/image3.gif, www/icons/index.gif, www/icons/layout.gif, www/icons/left.gif, www/icons/link.gif, www/icons/mailman-large.jpg, www/icons/mailman.jpg, www/icons/movie.gif, www/icons/p.gif, www/icons/patch.gif, www/icons/pdf.gif, www/icons/php4.gif, www/icons/pie0.gif, www/icons/pie1.gif, www/icons/pie2.gif, www/icons/pie3.gif, www/icons/pie4.gif, www/icons/pie5.gif, www/icons/pie6.gif, www/icons/pie7.gif, www/icons/pie8.gif, www/icons/portal.gif, www/icons/ps.gif, www/icons/quill.gif, www/icons/right.gif, www/icons/screw1.gif, www/icons/screw2.gif, www/icons/script.gif, www/icons/sound1.gif, www/icons/sound2.gif, www/icons/sphere1.gif, www/icons/sphere2.gif, www/icons/tar.gif, www/icons/tex.gif, www/icons/text.gif, www/icons/transfer.gif, www/icons/unknown.gif, www/icons/up.gif, www/icons/uu.gif, www/icons/uuencoded.gif, www/icons/world1.gif, www/icons/world2.gif, www/icons/yaws.gif, www/icons/yawsY.gif, www/icons/yaws_head.gif, www/icons/yaws_pb.gif, www/icons/small/README.txt, www/icons/small/back.gif, www/icons/small/binary.gif, www/icons/small/binhex.gif, www/icons/small/blank.gif, www/icons/small/broken.gif, www/icons/small/burst.gif, www/icons/small/comp1.gif, www/icons/small/comp2.gif, www/icons/small/compressed.gif, www/icons/small/continued.gif, www/icons/small/dir.gif, www/icons/small/dir2.gif, www/icons/small/doc.gif, www/icons/small/forward.gif, www/icons/small/generic.gif, www/icons/small/generic2.gif, www/icons/small/generic3.gif, www/icons/small/image.gif, www/icons/small/image2.gif, www/icons/small/index.gif, www/icons/small/key.gif, www/icons/small/movie.gif, www/icons/small/patch.gif, www/icons/small/ps.gif, bin/yaws, scripts/Makefile, scripts/mangle, scripts/yaws.conf, scripts/yaws.conf.template, scripts/yaws.ss, www/icons/small/rainbow.gif, www/icons/small/sound.gif, www/icons/small/sound2.gif, www/icons/small/tar.gif, www/icons/small/text.gif, www/icons/small/transfer.gif, www/icons/small/unknown.gif, www/icons/small/uu.gif: Initial revision �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������